JavaWeb笔记

发布时间 2023-12-26 15:08:55作者: htj10

JavaWeb笔记

Servlet

什么Servlet?

servlet 是运行在 Web 服务器中的小型 Java 程序(即:服务器端的小应用程序)。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。

编写一个servlet程序:

a、写一个java类,实现servlet接口

b、修改web.xml文件,给servlet提供一个可访问的URI地址

c、部署应用到tomcat服务器

d、测试:http://locahost:8080/day08_servlet/demo1

执行过程

Servlet生命周期(重要)

实例化-->初始化-->服务->销毁
出生:(实例化-->初始化)第一次访问Servlet就出生(默认情况下)
活着:(服务)应用活着,servlet就活着
死亡:(销毁)应用卸载了servlet就销毁。

小知识:
如何让servlet在服务器启动时就创建。

Servlet的三种创建方式

  • 实现javax.servlet.Servlet接口(参见:编写一个servlet程序:)

  • 继承javax.servet.GenericServlet类(适配器模式)

  • 继承javax.servlet.http.HttpServlet类(模板方法设计模式)
    (开发中常用方式)

Servlet --> GenericServlet --> HttpServlet  (继承HttpServlet)
曾祖父           爷爷              爸爸         孙子

servet映射细节

servet映射细节1:

servet映射细节2: 通配符* 代表任意字符串

url-pattern: *.do  以*.字符串的请求都可以访问 注:不要加/
url-pattern: /*  任意字符串都可以访问
url-pattern: /action/* 以/action开头的请求都可以访问
匹配规则:
优先级:从高到低
绝对匹配-->  /开头匹配 --> 扩展名方式匹配

如果url-pattern的值是/,表示执行默认映射。所有资源都是servlet

Servlet的线程安全

单实例:每次访问多线程
解决线程安全问题的最佳办法,不要写全局变量,而写局部变量。

Servlet获取配置信息

ServletConfig的使用

作用1:可以获取servlet配置信息
<servlet>
  	<servlet-name>demo3</servlet-name>
  	<servlet-class>com.love.servletcontext.ServletDemo3</servlet-class>
  	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
  </servlet>

方式1:

方式2:

方式3:

作用2:可以获得ServletContext对象

ServletContext(重要)

ServletContext: 代表的是整个应用。一个应用只有一个ServletContext对象。单实例。

作用:
域对象:在一定范围内(当前应用),使多个Servlet共享数据。

ServletContext的获取方式

  1. 通过request对象获取
    ServletContext sc = request.getServletContext();

  2. 通过HttpServlet获取

ServletContext sc = this.getServletContext();

两种方式获取到的对象是一样的。

常用方法:

void setAttribute(String name,object value);//向ServletContext对象的map中添加数据
Object getAttribute(String name);//从ServletContext对象的map中取数据
void rmoveAttribute(String name);//根据name去移除数据

获取全局配置信息:

修改web.xml文件:

String	getInitParameter(String name) //根据配置文件中的key得到value

获取文件MIME类型

String img = "a.png";
String type = sc.getMimeType(img);
// image/png

获取资源路径:

String  getRealPath(String path);//根据资源名称得到资源的绝对路径.

可以得到当前应用任何位置的任何资源。

实现Servlet的转发

RequestDispatcher  getRequestDispatcher(String path) ;//参数表示要跳转到哪去

Request / Respones

学好的关键:理解HTTP协议

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。

  • get_request请求原始字符串
GET /login.html?uname=aaaa&pwd=shsxt HTTP/1.1  --》请求行,下面都是请求头 key:value
Host: localhost:8888
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8

  • post_request请求原始字符串
POST /aaaa?uname=laopei HTTP/1.1   --》请求行,下面都是请求头 key:value,最后是请求正文
Host: localhost:8888
Connection: keep-alive
Content-Length: 22
Cache-Control: max-age=0
Origin: null
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8

//注意正文前有一个空行
pwd=soeasy&name=jj

  • response 响应返回原始
HTTP/1.1 200 OK             --> 响应行,下面是响应头,最后是响应正文
Date:Tue Dec 26 11:47:16 CST 2023
Server:shsxt Server/0.0.1;charset=UTF-8
Content-type:text/html;charset=UTF-8
Content-length:114 --> 正文的字节数

//正文前注意有一个空行
//正文
<html><head><title>服务器响应成功</title></head><body>shsxt server终于回来了。。。。</body></html>

HttpServlet

HttpServletResponse

响应行

HTTP/1.1 200 OK

setStatus(int sc) 设置响应状态码

响应头

//sendRedirect(String location) //(※)请求重定向
//setHeader(String name, String value) // 设置响应头信息
// ------------ 使用 --------------
//告知浏览器使用什么码表
response.setHeader("content-type", "text/html;charset=UTF-8");

//告知客户端不缓存
response.setHeader("pragma", "no-cache");
response.setHeader("cache-control", "no-cache");
response.setDateHeader("expires", 0);

Referesh刷新

响应正文(主体)

getWrite(); 字符输出流
getOutputStream(); 字节输出流
setCharacterEncoding(String charset) 告知服务器使用什么编码
setContentType(String type)
//告诉服务器用什么编码解析文本
//		resp.setCharacterEncoding("UTF-8");
//告诉客户端(浏览器)用什么编码显示
//		resp.setHeader("content-type", "text/html;charset=UTF-8");
		
//这句顶上面两句,即告诉服务器用什么编码解析文本,又告诉客户端(浏览器)用什么编码显示
resp.setContentType("text/html;charset=UTF-8");
		
PrintWriter out = resp.getWriter();
out.write("你好,中国!");

HttpServletRequest

请求行

Get http://localhost:8080/day09/servlet/req1?username=zs http/1.1

http://localhost:8080/HttpServlet/d6?username=tom&pwd=123
getMethod(); 获得请求方式     GET
***getRequestURL();返回客户端发出请求时的完整URL。http://localhost:8080/HttpServlet/d6
***getRequestURI(); 返回请求行中的资源名部分。/HttpServlet/d6
*****getContextPath(); 当前应用的虚拟目录。 /HttpServlet
getQueryString() ; 返回请求行中的参数部分。username=tom&pwd=123

请求消息头

 String   getHeader(String name)  根据头名称得到头信息值
 Enumeration   getHeaderNames()  得到所有头信息name
 Enumeration   getHeaders(String name)  根据头名称得到相同名称头信息值

请求正文(重要)

  • 与获取表单数据相关的方法
<input type="text" name="username" />
*** getParameter(name) 根据表单中name属性的名,获取value属性的值方法 
*** getParameterValues(String name)专业为复选框取取提供的方法
    getParameterNames() 得到表单提交的所有name的方法 
*** getParameterMap 得到表单提交的所有值的方法   //做框架用,非常实用
    getInputStream  以字节流的方式得到所有表单数据
  • 与操作非表单数据相关的方法(request也是一个域对象)
*** void setAttribute(String name, Object value);
*** Object getAttribute(String name);
    void removeAttribute(String name);
  • 与请求转发相关的方法
//得到请求转发或请求包含的协助对象
RequestDispatcher getRequestDispatcher(String path)
*** forward(ServletRequest request, ServletResponse response) //转发的方法
include(ServletRequest request, ServletResponse response) //请求包含

forward与include的区别:

  1. forward 是若转发前已经使用respond.getWriter()输出了内容,那么只要没有flush() ,forward依然可以成功,并会自动清除刚才的输出内容。但当调用了flush() ,则会报错。值得注意的是,执行了forward方法后,程序还会回来继续执行,此时再使用response输出已经没有作用了。建议可以在forward语句后加上if(true) return; 避免执行后面的程序。
  2. include 是服务器的动态加载,执行完第二个页面后可以回到第一个页面继续输出,只需要注意第二个页面不能更改response的头部信息。

总结:forward 是转发的另一个页面,include 是把另一个页面加载到当前页面。

  • 与请求编码相关的方法:
//解决post方式编码
*****request.setCharacterEncoding("UTF-8"); //告诉服务器客户端什么编码,只能处理post请求方式
//解决get方式编码
String name = new String(name.getBytes("iso-8859-1"),"UTF-8");
  • 与响应编码相关的方法
// ------ response ------
//告诉服务器用什么编码解析文本
//		resp.setCharacterEncoding("UTF-8");
//告诉客户端(浏览器)用什么编码显示
//		resp.setHeader("content-type", "text/html;charset=UTF-8");
		
//这句顶上面两句,即告诉服务器用什么编码解析文本,又告诉客户端(浏览器)用什么编码显示
resp.setContentType("text/html;charset=UTF-8");

重定向和转发的区别

重定向:

区别

会话Session

会话概述

什么是会话?
如同打电话
会话解决的问题?
保持各个客户端自己的数据

Cookie对象

由于cookie是由客户端浏览器保存和携带的,所以称之为客户端技术

属性:

  • name: 名称不能唯一确定一个cookie。路径可能不同
  • value: 不能存中文
  • path: 默认是写入cookie那个应用的访问路径
    如:http://localhost:8080/day10/servlet/cookieDemo1
    Path: /day10/servlet/
    当客户端访问服务器其它资源时,根据访问路径来决定是否带着cookie到服务器
    当访问的路径是以cookie中path开头的路径,就带cookie,否则就不带。
  • maxAge: cookie的保存时间。默认是-1(表示保存在浏览器的内存中)。单位是秒
    • 负数:cookie存在浏览器的内存中。
    • 0:删除。路径要保持一致,否则会删错了。
    • 正数:缓存(持久化到磁盘中)的时间。

Session对象

Session的状态:

为什么要学HttpSession?

  • 它也是一个域对象: session servletContext request
  • 同一个会话下,可以使一个应用的多个资源共享数据
  • cookie客户端技术,只能存字符串。HttpSession服务器端的技术,它可以存对象。

常用方法

把数据保存在HttpSession对象中,该对象也是一个域对象。

void setAttribute(String name,Object value);
Object getAttribute(String name);
void removeAttribute(String name);
HttpSession.getId():

setMaxInactiveInterval(int interval)  设置session的存活时间
invalidate() 使此会话无效

getSession():内部执行原理

HttpSession request.getSession():内部执行原理

1、获取名称为JSESSIONID的cookie的值。
2、没有这样的cookie,创建一个新的HttpSession对象,分配一个唯一的SessionID,并且向客户端写了一个名字为JSESSIONID=sessionID的cookie
3、有这样的Cookie,获取cookie的值(即HttpSession对象的值),从服务器的内存中根据ID找那个HttpSession对象:

找到了:取出继续为你服务。
找不到:从2开始。

HttpSession request.getSession(boolean create):

参数:
true:和getSession()功能一样。
false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。

客户端禁用Cookie后的会话数据保存问题

客户端禁用cookie:浏览器永远不会向服务器发送cookie的请求消息头

解决方案:
方案一:在主页上给出提示:请不要禁用您的cookie
方案二:URL重写。必须对网站的所有地址都重写。

http://url--->http://url;JSESSIONID=111

response.encodeURL(String url);
看浏览器有没有发送cookie请求消息头,没有就重写URL,有就不重写。

request.getSession();必须写

例子

JSP (Java Server Page)

请看:https://www.cnblogs.com/htj10/p/13197965.html


来自网上的教程进行编辑,侵权联系。