JavaWeb之Servlet详解

文章目录

  • 一,什么是Servlet
  • 二,Servlet
    • 1,Servlet是如何起作用的
    • 2,Servlet接口中的方法
    • 3,Servlet对象的生命周期
  • 三,ServletConfig
    • 1,什么是ServletConfig
    • 2,ServletConfig中的方法
  • 三,ServletContext
    • 1,什么是ServletContext
    • 2 ,ServletContext中的常用方法
    • 3,ServletContext与ServletConfig的区别与联系
    • 4,servletContext共享数据
  • 四,GenericServlet(适配器)
    • 1,什么是GenericServlet
    • 2,GenericServlet的设计目的
  • 五,HttpServlet
    • 1,什么是HttpServlet
    • 2,HttpServlet的设计目的
    • 3,HttpServlet执行流程
    • 4,HttpServlet使用总结
    • 5,模板方法设计模式
  • 六,HTTP协议
    • 1,什么是HTTP协议
    • 2,请求协议
      • 2.1 Get请求
      • 2.2 Post请求
    • 3,响应协议
    • 4,Get请求与Post请求区别
    • 5,缓存解决方案
  • 七,HttpServletRequest和HttpServletResponse
    • 1,HttpServletRequest接口
      • 1.1 什么是HttpServletRequest
      • 1.2 HttpServletRequest对象中的常用方法
    • 2,HttpServletResponse接口
      • 2.1 什么是HttpServletResponse
      • 2.2 HttpServletResponse对象中的常用方法
    • 3,请求转发与重定向
      • 3.1 请求转发
      • 3.2 重定向
      • 3.3 转发与重定向的异同
      • 3.4 什么时候采用转发,什么时候采用重定向?
      • 3.5 重定向解决页面刷新问题
  • 八,Cookie
    • 1,Cookie是什么?
    • 2,创建Cookie
    • 3, Cookie绑定路径
    • 4,浏览器何时发送Cookie
    • 5,Cookie有效时长
    • 6,Cookie的应用
  • 九,HttpSession
    • 1,Session概述
    • 2,获取Session对象
    • 3,Session实现原理
    • 4,Session对象生命周期
    • 5,HttpSession中的常用方法
    • 6,什么是一次会话?
    • 7,HttpSession的应用
  • 十,ServletContext、HttpServletRequest、HttpSession三者共享数据的区别
  • 十一,乱码问题与路径问题总结
    • 1,乱码问题
      • 1.1 为什么出现请求乱码?
      • 1.2 解决请求乱码的方法
      • 1.3 处理响应乱码
    • 2,路径问题
      • 2.1 Servlet中路径问题总结
      • 2.2 url-pattern的编写方式
  • 十二,Servlet 3.0

一,什么是Servlet

Servlet字面意思即服务端小程序
Servlet是一组接口、一组规范、一个协议;用于开发Web项目

一个工程的搭建通常由各模块组成;各个模块分工协作、相互配合可以高效率地构建大型项目。各个模块之间需要一组规范来连接,Servlet就是这样一组规范

B/S架构中涉及到的协议、标准、规范:

  • 浏览器和Web服务器之间的请求和响应遵循HTTP协议
  • WEB服务器和web项目的开发者(我们)之间有一些规范,例如:Servlet、JSP规范
  • Web项目的开发者(我们)和数据库服务器之间有一个规范,叫做JDBC规范

二,Servlet

1,Servlet是如何起作用的

每一个url都对应着互联网中的一个资源,分为静态资源和动态资源,例如:

  • http://202.108.251.34:8080/egov/login.html请求路径对应着一个html网页资源
  • http://202.108.251.34:8080/oa/delete?empno=7369请求路径对应着一个动态资源、一段程序

这段程序就是Servlet程序,当浏览器发送某个请求时,服务器找到该请求对应的servlet程序并执行servlet对象的service()方法。请求路径与servlet程序的对应信息配置在web.xml文件中,如图:
JavaWeb之Servlet详解_第1张图片

2,Servlet接口中的方法

javax.servlet.Servlet接口

public interface Servlet {
	/**
	初始化方法,servlet对象创建之后会执行该方法;servlet对象为单例对象,故该方法只执行一次
	*/
    void init(ServletConfig config) throws ServletException;
	/**
	获取servletConfig对象,该对象由服务器创建并传入
	*/
    ServletConfig getServletConfig();
	/**
	主体方法,用于处理业务逻辑,服务器通过请求路径找到对应的servlet对象并执行该方法;由服务器传入请求和响应对象
	*/
    void service(ServletRequest request, ServletResponse response) throws ServletException, IOException;
	/**
	返回有关servlet的信息,例如作者,版本和版权
	*/
    String getServletInfo();
	/**
	销毁前的准备,servlet对象销毁前会执行该方法
	*/
    void destroy();
}

3,Servlet对象的生命周期

Servlet对象从最初的创建,方法的调用,到最后被销毁,都是由web容器来管理的,javaweb程序员无权干涉

具体过程:

  1. Web容器启动,解析web.xml文件,将请求路径与对应的servlet类名放到一个map集合中,如图:JavaWeb之Servlet详解_第2张图片
    大多数web容器还会维护一个请求路径与对应的servlet对象的集合,如图:JavaWeb之Servlet详解_第3张图片
    默认情况 下,servlet对象在Web容器启动阶段不会被实例化,而是在接收到第一次请求之后实例化;若想要在web容器启动时实例化,可进行如下配置:JavaWeb之Servlet详解_第4张图片
  2. 浏览器发送请求,web容器截取请求路径,通过请求路径在Map中查找对应的servlet对象;
    如果没有找到对应的servlet对象,则:
    1,通过请求路径在Map找到对应的servlet全类名
    2,通过反射机制加载该类并调用无参构造方法完成servlet对象实例化
    3,调用servlet对象的init()方法完成初始化
    4,调用servlet对象的service()方法提供服务
    若找到了对应的servlet对象,则调用该对象的service()方法提供服务
  3. servlet对象销毁:web容器关闭的时候、webApp重新部署的时候、该servlet对象长时间没有用户访问的时候,web容器会将servlet对象销毁,在销毁servlet对象前,会调用对象的destroy()方法进行销毁前的准备

注意:servlet对象是单例,web容器为每个Servlet类只创建一个servlet对象

三,ServletConfig

1,什么是ServletConfig

  1. ServletConfig指javax.servlet.ServletConfig接口
  2. 【了解】Apache Tomcat服务器实现了Servlet规范,Tomcat服务器写了一个ServletConfig接口的实现类,实现类的完整类名是org.apache.catalina.core.StandardWrapperFacade
  3. ServletConfig对象封装了Servlet对象的配置信息,每个Servlet对象对应着一个ServletConfig对象;在web.xml中,ServletConfig对象对应着标签中的所有内容,例如:
    JavaWeb之Servlet详解_第5张图片
  4. ServletConfig对象由服务器创建并在servlet对象初始化时传入: void init(ServletConfig servletConfig) throws ServletException;
  5. 在service()方法体中,可以通过getServletConfig()方法获取ServletConfig对象:JavaWeb之Servlet详解_第6张图片

2,ServletConfig中的方法

public interface ServletConfig {
	//获取servletName: servletName
    String getServletName();
	//获取ServletContext对象,ServletContext为Servlet的上下文环境,下章节讲
    ServletContext getServletContext();
    /**
    获取初始化参数name对应的value
	
            driver
            com.mysql.jdbc.driver
    
    */
    String getInitParameter(String paranmae);
	/**
	获取初始化参数的name集合的枚举(类似迭代器):
	Enumeration initParameterNames = servletConfig.getInitParameterNames();
	通过name集合循环遍历拿出name,通过name获取value
	while (initParameterNames.hasMoreElements()) {
    	String name = initParameterNames.nextElement();
    	String value = servletConfig.getInitParameter(name);
	}
	*/
    Enumeration<String> getInitParameterNames();
}

三,ServletContext

1,什么是ServletContext

  1. ServletContext指javax.servlet.ServletConfig接口

  2. ServletContext对象由服务器创建,Tomcat服务器对ServletContext接口的实现类完整类名是:org.apache.catalina.core.ApplicationContextFacade

  3. ServletContext意为servlet的上下文环境,servletContext对象对应着整个项目,该对象只有一个且被所有servlet共享,servletContext对象对应着web.xml文件,例如:JavaWeb之Servlet详解_第7张图片

  4. web.xml文件服务器启动阶段被解析,servletContext对象在服务器启动阶段被创建,在服务器关闭时被销毁

2 ,ServletContext中的常用方法

/**
根据参数的名称获取value,均为字符串

        driver
        com.mysql.jdbc.driver

*/
String getInitParameter(String paraname);
//与ServletConfig中的方法作用相同
Enumeration<String> getInitParameterNames();
//向ServletContext对象中添加数据
void setAttribute(String name, Object obj);
//根据name从ServletContext对象中获取数据
Object getAttribute(String name);
//从ServletContext对象中移除数据
void removeAttribute(String name);
//获取文件绝对路径
String getRealPath(String path);

3,ServletContext与ServletConfig的区别与联系

  1. 每一个servlet对象对应着一个servletConfig对象;所有的servlet对象共同对应着一个servletContext对象
  2. servletConfig中包含了所对应的servlet的参数配置信息;servletContext中包含了整个项目的参数配置信息,所有的servlet共享该配置信息
  3. servletConfig和servletContext对应的参数配置信息均在web.xml文件中,位置如下:JavaWeb之Servlet详解_第8张图片

4,servletContext共享数据

由于所有的servlet共同对应着一个servletContext,不同的servlet、不同的用户可以通过一下两个方法共享数据

//向ServletContext对象中添加数据
void setAttribute(String name, Object obj);
//根据name从ServletContext对象中获取数据
Object getAttribute(String name);

四,GenericServlet(适配器)

1,什么是GenericServlet

GenericServlet即通用Servlet,是一个抽象类,实现了Servlet接口

2,GenericServlet的设计目的

  1. GenericServlet的设计采用了适配器设计模式
  2. 在GenericServlet没有出现之前,我们编写的Servlet类需要直接实现Servlet接口,但是这个接口中有些方法是目前不需要的,有些操作又是每个Servlet类必备的,例如在init()方法中给config成员赋值,我们大多数情况只需要编写不同的service()方法。直接实现Servlet接口的代码丑陋,有必要在中间添加一个适配器,以后所有的Servlet类不再直接实现Servlet接口,而而是去继承GenericServlet
  3. GenericServlet中只含有一个抽象方法,即service(),子类必须实现,编写业务逻辑
  4. GenericServlet中提供了一个重载的无参数的init()方法,若想在servlet初始化时执行一段特殊的代码,建议重写此无参数的init()方法
  5. 除了让代码变得优雅之外,GenericServlet中又提供了一些额外的方法,例如:public String getInitParameter(String name);public ServletContext getServletContext();子类继承之后,可以在子类中直接使用,方便编程

五,HttpServlet

1,什么是HttpServlet

HttpServlet是一个模板类、抽象类,继承于GenericServlet

2,HttpServlet的设计目的

  • HttpServlet是针对于HTTP协议的,为了处理http请求和响应。不同类型的请求会由不同类型的Servlet处理,对于JavaWeb程序员,我们只需要关注HttpServlet即可
  • 为了使前后端的请求方式相同,我们需要在后端获取请求方式,然后进行判断前端发送的请求是否为规定的请求方式,如果不是规定的请求方式,就会报错;
  • 为了实现上述功能,需要在每一个GenericServlet的子类中编写实现此功能的代码,代码臃肿;为了解决这个问题,Sun公司提供了HttpServlet抽象类封装了实现上述功能的代码

3,HttpServlet执行流程

  1. service(ServletRequest req, ServletResponse res)方法将两个参数转化为HttpServletRequest和HttpServletResponse类型的
  2. service(HttpServletRequest request, HttpServletResponse response)方法获取请求方法;判断,如果是Get请求就执行doGet()方法,如果是Post请求就执行doPost()方法
  3. doGet()/doPost()执行业务代码

注意:HttpServlet提供的doGet()方法和doPost()方法是用来报错的、是用来让我们重写的

所以,我们编写的的Servlet类继承HttpServlet后,后端需要的是什么请求,那么我们就重写对应的doPost()/doGet()方法,方法内是我们的业务代码,并不需要重写service()方法

4,HttpServlet使用总结

  1. 我们的Servlet继承HttpServlet后,后端需要的是什么请求,那么我们就重写对应的doPost()/doGet()方法
  2. doPost()/doGet()方法内就是我们的业务代码,doXXX()可以看作main()方法
  3. 代码不在service()内编写了,不需要重写service()方法
  4. HttpServlet中重载的两个service()方法并不需要也没有理由去重写这两个方法
  5. 当浏览器发送的请求方式和后台处理方式不同时,会出现一个错误,代号:405

5,模板方法设计模式

模版方法设计模式属于行为行设计模式
模版方法有一个特点:doXXX()
模板方法设计模式的主要作用:

  • 核心算法得到保护
  • 核心算法得到复用
  • 在不改变算法的前提下,却可以重新定义算法步骤的具体实现

模板方法设计模式的例子:

  • Servlet规范中的HttpServlet
  • HttpServlet就是一个典型的模板方法设计模式
  • HttpServlet是一个模板类
  • 其中的service(HttpServletRequest, HttpServletResponse)方法是典型的模板方法,该方法中定义了核心算法骨架,doGet()、doPost()…具体的实现细节延迟到子类中完成

六,HTTP协议

1,什么是HTTP协议

  • 超文本传输协议
  • 浏览器和服务器之间的一种通讯协议
  • 该协议时W3C负责制定的,其本质上就是数据传送格式,提前指定好了的。浏览器和服务器都必须按照这种格式接收与发送数据
  • HTTP协议是无连接、无状态的:请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束后,通道关闭;这样做的目的是降低服务器的压力

2,请求协议

请求协议包括四部分:
1,请求行
2,消息报头
3,空白行
4,请求体
请求行包括:请求方式 URI 协议版本号
空白行:专门用来分离消息报头和请求体的

2.1 Get请求

JavaWeb之Servlet详解_第9张图片

2.2 Post请求

JavaWeb之Servlet详解_第10张图片

3,响应协议

响应协议包括四部分:状态行、响应报头、空白行、响应体

状态行:协议版本号 状态码
空白行:是用来分离响应报头和响应体的
响应协议中重点掌握状态码:

  • 200 响应成功正常结束
  • 404 资源未找到
  • 500 服务器内部错误

JavaWeb之Servlet详解_第11张图片

4,Get请求与Post请求区别

(1), 什么情况下浏览器发送的请求是GET请求,什么情况下浏览器发送的请求是POST请求?
只有当使用表单form,并且讲form的标签的method属性设置为method=“post”,才是POST请求方式,其余剩下的所有请求都是基于GET请求

(2), GET请求和POST请求有什么区别?

  • GET请求在请求行上提交数据,格式uri?name=value&name=value,这种提交方式最终提交的数据会显示在浏览器地址栏上
  • POST请求在请求体中提交数据,相对安全,提交格式name=value&name=value,这种提交方式最终不会显示在浏览器地址栏上
  • POST请求在请求体中提交数据,所以POST请求提交的数据没有长度限制【POST可以提交大数据】
  • GET请求在请求行上提交数据,所以GET请求提交的数据长度有限制
  • GET请求只能提交字符串数据,POST请求可以提交任何类型的数据,包括视频…,所以文件上传必须使用POST请求
  • GET请求最终的结果,会被浏览器缓存收纳,而POST不会被缓存收纳(为什么GET会被缓存?)

(3),GET请求和POST请求应该如何选择?

  • 有敏感数据 POST
  • 传送的数据不是普通字符串 POST
  • 传送的数据非常多 POST
  • 这个请求是为了修改服务器端资源 POST
  • GET请求多数情况下是从服务器中读取资源,这个读取的资源在短时间内不会发送变化,所以GET请求最终的结果会被浏览器缓存起来
  • POST请求是为了修改服务器端的资源,而每一次修改结果都是不同的,最终结果没有必要被浏览器缓存

5,缓存解决方案

浏览器将资源缓存后,缓存的资源是和某个特定的路径绑定在一起的,只要浏览器再发送这个相同的请求路径,这个时候浏览器就会去缓存中获取资源,不再访问服务器,以这种方式降低服务器的压力,提高用户体验。

但是有的时候我们并不希望走缓存,希望每一次后哦访问服务器,可以在请求路径后面添加时间戳,例如:http://ip:port/oa/system/logout?timetamp=1234564635423

七,HttpServletRequest和HttpServletResponse

1,HttpServletRequest接口

1.1 什么是HttpServletRequest

  • HttpServletRequest是一个接口,继承于ServletRequest
  • HttpServletRequest接口的实现类是由Web容器负责的,Tomcat服务器有自己的实现
  • 每当浏览器发送一个请求,服务器接收到该请求并创建一个HttpServletRequest对象,httpServletRequest对象中封装了该请求的所有信息。在执行servlet的service()方法时将该对象传入

1.2 HttpServletRequest对象中的常用方法

表单提交的数据会封装在request对象的Map集合中,key是name,value是字符串类型的一个一维数组,如下:JavaWeb之Servlet详解_第12张图片

/*获取浏览器提交的数据*/
String getParameter(String name) //获取name对应的一维数组的首元素
Map getParameterMap() //获取request对象中的Map集合
Enumeration getParameterNames() //返回name集合的枚举,与ServletConfig、ServletContext中的getInitParameterNames()作用相同
String[] getParameterValues(String name) //返回String数组,数组包含name对应的多个value值

/*获取路径、URL、URI、IP*/
String getContextPath() //获取上下文路径(web项目根路径),资源的根路径
String getMethod() //获取浏览器请求方式
String getRequestURI() //获取请求的URI
StringBuffer getRequestURL() //获取请求的URL
String getServletPath() //获取请求的ServletPath,即servlet对应的请求路径
String getRemoteAddr() //获取客户端IP地址

/*从一次请求对应的HttpServletRequest对象范围中增删查数据*/
Object getAttribute(String name) //从此次请求对应的request对象范围中获取数据
void setAttribute(String name, Object o) //从此次请求对应的request对象范围中存储数据
void removeAttribute(String name) //从此次请求对应的request对象范围中删除数据

/*请求转发器*/
RequestDispatcher getRequestDispatcher(String path) //获取请求转发器,用于请求转发

/*编码*/
void setCharacterEncoding(String env) //覆盖此请求正文中使用的字符编码的名称(针对post请求才起作⽤)

/**/
HttpSession getSession() //返回与此请求关联的当前会话,如果该请求没有会话,则创建一个并返回。
HttpSession  session=request.getSession(true);//获取session对象,若没有获取到则新建session对象并返回;与getSession()作用相同
HttpSession  session=request.getSession(false);//获取session对象,若没有获取到则返回null
Cookie[] getCookies() //返回一个Cookie数组,其中包含浏览器端发送过来的包含在请求中的所有cookie

//Cookie和Session下面章节讲

2,HttpServletResponse接口

2.1 什么是HttpServletResponse

  • 与HttpServletRequest一样,HttpServletResponse是一个接口,继承于ServletResponse;HttpServletResponset接口的实现类是由Web容器负责的,Tomcat服务器有自己的实现
  • 服务器接收到请求之后会作出响应,httpServletResponse对象封装了响应消息

2.2 HttpServletResponse对象中的常用方法

void addCookie(Cookie cookie) //给这个响应添加⼀个cookie
void sendRedirect(String s) //重定向,发送⼀条响应码,将浏览器跳转到指定的位置
PrintWriter getWriter() //获得字符输出流,通过字符流的write(String s)⽅法可以将字符串输出到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
void setContentType(String s) //设置响应内容的类型,例如:response.setContentType("text/html;charset=UTF-8");

3,请求转发与重定向

3.1 请求转发

步骤:

  1. 获取请求转发器对象
  2. 调用请求转发器的forward()方法即可完成转发

例如:

//请求转发到/b对应的Servlet
request.getRequestDispatcher("/b").forward(request,response);

特点: 在浏览器端进行一次请求,服务器端将请求从一个Servlet转发给另一个Servlet…,浏览器端的地址不变,但是实际上可能后台是好几个Servlet依次处理浏览器的请求,并响应给浏览器。请求转发可以使不同的servlet共享同一个request中的数据,通过以下方法:

Object getAttribute(String name) //从此次请求对应的request对象范围中获取数据
void setAttribute(String name, Object o) //从此次请求对应的request对象范围中存储数据
void removeAttribute(String name) //从此次请求对应的request对象范围中删除数据

3.2 重定向

服务器将请求路径反馈给浏览器,浏览器又向web服务器发送了一次全新的请求;例如:

response.sendRedirect(request.getContextPath() + "/b");

3.3 转发与重定向的异同

  • 相同点:都可以完成资源的跳转、页面的跳转
  • 不同点:
    • 转发是request对象触发的,服务器内部进行转发
    • 重定向是response对象触发的,要将重定向的路径响应给浏览器
    • 转发是一次请求,浏览器地址栏上地址不变
    • 重定向是两次请求,浏览器地址栏上的地址发生变化
    • 重定向路径需要加项目名(webapp根路径web目录),因为该路径由浏览器解析
    • 转发是在本项目内部完成资源的跳转
    • 重定向可以完成跨网站跳转,例如可以跳转到https://www.baidu.com

3.4 什么时候采用转发,什么时候采用重定向?

大部分情况下都使用重定向

  • 若想完成跨app跳转,必须采用重定向
  • 若在上一个资源中向request范围中存储了数据,希望在下一个资源中从request范围中取出,必须使用转发
  • 重定向可以解决浏览器的刷新问题

3.5 重定向解决页面刷新问题

假设现在浏览器端发送向数据库中插入一条数据的请求,插入成功后跳转到成功页面

使用转发:

  • 浏览器提交请求后,后台进行转发到access.html成功页面,浏览器只进行了一次请求,如果此时浏览器进行刷新,那么就会刷新最后一次提交表单的请求,会导致因为多次刷新而提交多次请求,导致后台执行多次Servlet,导致数据库插入多条重复记录

使用重定向:

  • 浏览器提交请求后,后台通过重定向,将重定向的地址(/webapp17/access.html)发送给浏览器,浏览器会请求重定向的地址;这个过程中一共有两次请求;此时浏览器进行刷新,刷新的是最后一次重定向地址的请求,请求的资源是access.html,多次刷新就会多次请求access.html,并不会导致多次提交插入数据的请求!

八,Cookie

1,Cookie是什么?

  • Cookie可以保存信息(保存在浏览器端上),其中保存了String类型的name-value(键值对)
  • Cookie可以保存会话状态,这个会话状态是保留在客户端(浏览器端)上的; 只要Cookie清除,或者Cookie失效,这个会话状态就没有了【应用在Session中,请看下一章节】
  • Cookie是保存在浏览器客户端上的
  • Cookie默认保存在浏览器的缓存中,浏览器关闭Cookie消失
  • Cookie可以保存在客户端硬盘文件中,浏览器关闭Cookie还在,除非Cookie消失(有效时长完结)

2,创建Cookie

服务器创建Cookie并发送给浏览器

//创建cookie
Cookie cookie = new Cookie(String name, String value);
//设置Cookie有效期
cookie.setMaxAge(60*60*60);
//设置Cookie绑定的路径
cookie.setPath("/webapp/user");
//将cookie发送给浏览器
response.addCookie(cookie);

3, Cookie绑定路径

Cookie未绑定路径时默认绑定的路径:

在默认情况下,未设置Cookie绑定路径的Cookie,会绑定当前访问路径的上一层路径(带"/"),如:

  • 访问/webapp/test/a路径时,服务器发送的Cookie(此Cookie未人为设置绑定路径),那么此Cookie默认绑定的路径未/webapp/test/,所以访问/webapp/test/、/webapp/test/···时都会将此Cookie发送给服务器

Cookie绑定路径:

cookie.setPath();来设置此Cookie绑定的访问路径;当设置此Cookie绑定的路径时,浏览器只有访问此路径,以及此路径下的其他资源时,浏览器才会将此Cookie发送到服务器

如下:那么此Cookie只有浏览器访问/webapp19/user路径,以及/webapp/user/···等等其他此路径下的其他资源时,浏览器才会将此Cookie发送到服务器

cookie.setPath("/webapp/user");

4,浏览器何时发送Cookie

只有当浏览器访问Cookie绑定的路径以及此路径下的其他资源时,浏览器才会将Cookie发送给服务器

5,Cookie有效时长

通过方法cookie.setMaxAge(int expiry)

  • 值为正数,以秒为单位指定Cookie的最长期限,Cookie存储在硬盘文件当中;
  • 值为负数,则此Cookie在关闭此窗口页面后即失效;
  • 如果为零,则删除此Cookie;

例如:以下设置Cookie有效期为24小时

cookie.setMaxAge(60*60*24);

6,Cookie的应用

例如:实现十天内免登录,将用户名和密码保存在cookie中,每当访问登录页面时发送给服务器,服务器验证

九,HttpSession

1,Session概述

  1. Cookie可以将会话状态保存在客户端,而HttpSession可以将会话状态保存在服务器端
  2. HttpSession对象是一个会话级别的对象,一次会话对应一个HttpSession对象
  3. 在会话进程中,web服务器一直为当前这个用户维护着一个会话对象HttpSession
  4. 在web容器中,维护了大量的HttpSession对象,这些对象放在一个Map集合中

2,获取Session对象

HttpSession  session=request.getSession();//与getSession(true)作用相同
HttpSession  session=request.getSession(true);//获取session对象,若没有获取到则新建session对象并返回;(无参数默认为true)
HttpSession  session=request.getSession(false);//获取session对象,若没有获取到则返回null

3,Session实现原理

1,浏览器发送请求,服务器对应的Servlet首次调用request.getSession(true);方法时获取Session对象:

  • 服务器会创建一个Session对象,同时创建一个对应的Cookie对象,并且Cookie对象的name是JSESSIONID,Cookie的value是32位长度的字符串
  • 服务器将Cookie的value和HttpSession对象绑定到session列表中(Map集合)
  • 服务器将Cookie发送到客户端浏览器,浏览器将Cookie保存到缓存中

2, 浏览器再次发送请求,会自动提交Cookie(前提是同一个绑定路径下)

  • 当服务器Servlet再次调用request.getSession();方法时获取Session对象
  • 服务器接收到Cookie,验证Cookie的name为JSESSIONID,然后获取Cookie的value
  • 通过Cookie的value去session列表(Map集合)中检索对应的HttpSession对象

4,Session对象生命周期

web系统中引入了session超时的概念,当很长一段时间(这个时间可以配置)没有用户再访问session对象,此时session对象超时,web服务器自动回收session对象

设置Session对象失效时间(两次请求之间的最大时间间隔),优先级 1 > 2 > 3

  1. 通过Java代码实现,单位秒在这里插入图片描述
  2. 修改项目的web.xml文件,单位分钟在这里插入图片描述
  3. 修改Tomcat默认配置,单位分钟,默认30分钟JavaWeb之Servlet详解_第13张图片

5,HttpSession中的常用方法

void setAttribute(String name, Object value) //向会话范围中存储数据

Object getAttribute(String name) //从会话范围中获取数据

void removeAttribute(String name) //从会话范围中移除某个数据

void invalidate() //销毁session对象

void setMaxInactiveInterval(int interval) //设置session对象失效时间(浏览器向服务器两次请求之间最大时间间隔,超过最大设置时间间隔则销毁此session)

6,什么是一次会话?

  • 一般可以这样理解:用户打开浏览器,在浏览器上发送多次请求,直到最终浏览器关闭,表示一次完整的回话。
  • 本质上理解:Session对象创建到最终超时销毁,才是真正意义的一次会话;因为即使浏览器关闭,可以通过重写URL的方式从其他电脑其他浏览器同样使用这个Session对象。

7,HttpSession的应用

例如:报存用户登录状态,验证用户是否已登录

十,ServletContext、HttpServletRequest、HttpSession三者共享数据的区别

  • ServletContext、HttpSession、HttpServletRequest对象都是范围对象。
  • ServletContext是应用范围,整个项目、所有的Sevlet、所有的用户共享
  • HttpSession是会话范围,同一个用户、同一个会话中多次请求共享
  • HttpServletRequest是请求范围,单次请求共享(请求转发)
  • 三者都可以通过void setAttribute(String name, Object value) 和 Object getAttribute(String name)方法共享数据
  • application完成跨用户共享数据;
    session完成跨请求共享数据,但是这些请求必须在同一个会话当中;
    request完成跨Servlet共享数据,但是这些servlet必须在同一个请求当中(请求转发)
  • 使用原则:由小到大尝试,优先使用小范围

十一,乱码问题与路径问题总结

1,乱码问题

1.1 为什么出现请求乱码?

浏览器对请求数据的编码方式和服务器对请求数据的解码方式不同。Get请求的数据在URL中,属于URL编码;Post请求数据的编码方法即页面的编码方式

  • 以Tomcat7.0为例,Tomcat会使用默认的ISO-8859-1进行解码,此时字符集可能与浏览器端编码的字符集不同而出现乱码

1.2 解决请求乱码的方法

(1)适用于Post请求和Get请求

//获取乱码字符
String value = request.getParameter("name");
//将乱码字符通过错误的ISO-8859-1编码方式重新还原回去
byte[] bytes = value.getBytes("ISO-8859-1");
//再通过正确的编码方式进行解码
value = new String(bytes, "UTF-8");

(2)仅支持Post请求

//设置字符编码方式
request.setCharacterEncoding("UTF-8");
//获取正确的字符
String value = request.getParameter("name");

(3)仅支持Get请求
JavaWeb之Servlet详解_第14张图片
注:Tomcat8之后针对于Get请求服务器会在程序中解决字符编码的问题;所以我们只需要处理Post请求的乱码问题即可

1.3 处理响应乱码

在获取输出流对象之前设置输出内容的类型和字符集,例如:

	response.setContentType("text/html;charset=UTF-8");
    PrintWriter writer = response.getWriter();

2,路径问题

2.1 Servlet中路径问题总结

web工程servlet中反斜杠"/"的表示含义:

如果路径是在浏览器端被解析,则"/“表示"http://ip地址:port/”
如果路径是在服务器端被解析,则"/“表示"http://ip地址:port/项目名/”

下面罗列了一些web工程中"/"的使用场景:

1,浏览器端被解析的场景:

2,服务器端被解析的场景:

  • Servlet路径:
    JavaWeb之Servlet详解_第15张图片

  • 请求转发:request.getRequestDispatcher("/资源路径").forward(request,response);

  • 获取资源的真实绝对路径:context.getRealPath("/资源路径");

2.2 url-pattern的编写方式

  • 一个Servlet可以编写多个url-pattern
  • 精确匹配:
    在这里插入图片描述
  • 扩展匹配:
    在这里插入图片描述
  • 后缀匹配:
    在这里插入图片描述
  • 全部匹配:
    在这里插入图片描述

十二,Servlet 3.0

从Servlet3.0开始,配置Servlet⽀持注解⽅式,同时保留了配置web.xml的⽅式。这降低了配置xml所花费的时间和精力。

服务器会在启动时读取注解

@WebServlet常⽤属性
JavaWeb之Servlet详解_第16张图片
例如:JavaWeb之Servlet详解_第17张图片
注意:根元素web.xml中不能配置属性metadata-complete=“true”,否则⽆法加载Servlet。metadata-complete属性表示通知Web容器是否寻找注解,默认不写或者设置false,容器会扫描注解,为Web应⽤程序构建有效的元数据;如果设置metadata-complete=“true”,会在启动时不扫描注解(annotation)。如果不扫描注解的话,⽤注解进⾏的配置就⽆法⽣效,例如:@WebServlet

你可能感兴趣的:(笔记,java,servlet,javaweb)