前言
JavaWeb三大组件指的是:Servlet 程序、Filter 过滤器、Listener 监听器,它们在JavaWeb开发中分别提供不同的功能,然而很多人有只用过Servlet、Filter,很少接触到Listener,甚至有些人对然而很多人有只用过Servlet都不熟悉,因为在企业开发中,都是使用框架的封装好的,很少接触到原生的JavaWeb组件,充其量就是使用Filter拦截请求,过滤响应,所以很多人上来就直接学框架。
其实这种做法很不可取,虽然随着技术的发展,已经没有人再使用原生JavaWeb开发了,加之前后端分离,像JSP、JDBC等技术都没有了专门学习的必要了。但是JavaWeb的三大组件却是十分重要,框架都是对原生JavaWeb进行封装的结果,像SpringMVC的核心就是Servlet,涉及到Listener的框架就更多了,而Filter不仅在框架使用,日常开发中也经常被用到,所以要深入理解框架,就必须熟练掌握JavaWeb的三大组件。
一、Servlet 程序
Servlet是什么?
Servlet是JavaEE规范(接口)之一;
Servlet是运行在服务器(Web容器Tomcat等)上的一个 java 小程序,它用来接收客户端发送过来的请求进行处理,并响应数据给客户端。
Servlet及相对的对象,都由Tomcat创建,我们只是使用。
Servlet需要完成3个任务:
- 接收请求:将客户端发送过来的请求封装成ServletRequest对象(包含请求头、参数等各种信息)
- 处理请求:在service方法中接收参数,并且进行处理请求。
- 数据响应:请求处理完成后,通过转发(forward)或者重定向(redirect)到某个页面。
转发(forward)或者重定向(redirect)的区别? 本质:forward是HttpServletRequest的方法,redirect是HttpServletResponse的方法。 现象及结果: 1. forward客户端只发了一次请求,在服务端进行转发行为,可以共享数据(request中参数),浏览器URL不改变。 2. redirect是服务端向客户端完成响应后,客户端再次发起一个请求,不可以共享数据(request中参数),请求了两次,浏览器URL改变。
Servlet的生命周期
- 执行 Servlet 构造器方法
第一步,在web.xml中的servlet中配置 load-on-startup 的值 ≥ 0 时,表示应用启动时就创建这个servlet。否则,第一次访问的时候调用。 - 执行 init 初始化方法
第二步,第一次访问的时候调用。 - 执行 service 方法
第三步,每次访问都会调用。 - 执行 destroy 销毁方法
第四步,在 web 工程停止的时候调用。
通过实现 Servlet 接口 实现Servlet程序
- 实现Servlet接口,重写service方法,处理请求,并响应数据
- 在web.xml中配置servlet程序的访问地址。
web.xml 中的配置:
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.demo.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
通过继承 HttpServlet 实现Servlet程序(推荐,一般开发中使用这种方式)
- 继承 HttpServlet类,按业务需求重写doGet 或 doPost 方法,处理请求
- 到 web.xml 中的配置 Servlet 程序的访问地址
代码比实现Servlet接口的方式更加简单,不需要进行请求的类型转换,配置与实现Servlet接口的方式一样,所以这里不做演示
ServletConfig(Servlet程序的配置信息类)
在Servlet 程序创建时,就会创建一个对应的 ServletConfig 对象。
它的三大作用:
- 获取web.xml 中 Servlet 程序的别名 servlet-name 的值
- 获取web.xml 中 Servlet 程序的获取初始化参数 init-param
- 获取 ServletContext 对象
ServletContext (Servlet上下文) 接口
- 每个web项目只有一个ServletContext对象,在web工程部署启动的时候创建,在工程停止的时候关闭。
- ServletContext 对象是一个域对象(可以像Map一样存储数据的对象。域指的是作用域,这里是整个web工程)。
ServletContext 类的四个作用:
- 获取 web.xml 中配置的上下文参数 context-param
- getContextPath()获取当前的工程路径,格式: /工程路径
- getRealPath()获取工程部署后在服务器硬盘上的绝对路径
- 像 Map 一样存取数据
HttpServletRequest 和 HttpServletResponse
HttpServletRequest
HttpServletRequest继承了ServletRequest,每次请求进入tomcat服务器,tomcat容器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息
HttpServletResponse
HttpServletResponse 类和 HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个 Response 对象传递给 Servlet 程序去使用。通过 HttpServletResponsee 对象来进行设置返回给客户端的信息
解决请求的中文乱码
- Get请求:获取请求参数,先以 iso8859-1 进行编码,再以 utf-8 进行解
- Post请求:调用req.setCharacterEncoding("UTF-8"), 设置请求体的字符集为 UTF-8;
解决响应的中文乱码
方案一(推荐):
// 它会同时设置服务器和客户端都使用 UTF-8 字符集,还设置了响应头
// 此方法一定要在获取流对象之前调用才有效
resp.setContentType("text/html; charset=UTF-8")
方案二(不推荐):
// 设置服务器字符集为 UTF-8
resp.setCharacterEncoding("UTF-8");
// 通过响应头,设置浏览器也使用 UTF-8 字符集
resp.setHeader("Content-Type", "text/html; charset=UTF-8"
Filter
Filter 是JavaEE规范(接口)之一;
Filter 过滤器它的作用是:拦截请求,过滤响应。
常见应用场景:
1、权限检查
2、日记操作
3、事务管理
……等等
Filter 过滤器的使用步骤:
1、实现 Filter 接口,实现过滤方法 doFilter()
2、到 web.xml 中去配置 Filter 的拦截路径
web.xml 中的配置:
<filter>
<filter-name>AdminFilter</filter-name>
<filter-class>com.demo.filter.AdminFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AdminFilter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
Filter 的生命周期
- 构造器方法
- init 初始化方法
第 1,2 步,在 web 工程启动的时候执行(Filter 已经创建) - doFilter 过滤方法
第 3 步,每次拦截到请求,就会执行 - destroy 销毁
第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)
FilterConfig(Filter过滤器配置类)
Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息。
FilterConfig 类的作用是获取 filter 过滤器的配置内容:
- 获取 Filter 的名称 filter-name 的内容
- 获取在 Filter 中配置的 init-param 初始化参数
- 获取 ServletContext 对象
FilterChain 过滤器链
在多个Filter执行的时候,它们执行的优先顺序由它们在web.xml中从上到下配置的filter-mapping顺序决定,与filter的配置顺序无关!!!
过滤器链(多个Filter执行)的特点:
- 所有filter和目标资源默认都执行在一个线程中。
- 多个filter共同执行的时候,它们使用的是同一个Request对象。
Filter 的3种拦截路径匹配规则:
- 精确匹配 /target.jsp
- 目录匹配 /admin/*
- 后缀名匹配 *.html
Filter 过滤器它只关心请求的地址是否匹配,不关心请求的资源是否存在!!!
Listener
用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。本质是观察者模式。
Servlet监听器:Servlet规范中定义的一种特殊类,它用于监听Web应用程序中的ServletContext,HttpSession 和HttpServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。
监听器分为3类
- 域对象监听器
- 域对象的属性域监听器
- Session域中数据的监听器
八大监听器
- ServletContextListener
监听ServletContext对象的创建与销毁
在SpringMVC中,有个ContextLoaderListener,这个监听器就实现了ServletContextListener接口,表示对ServletContext对象本身的生命周期进行监控
2. HttpSessionListener
监听HttpSession对象的创建与销毁
3. ServletRequestListener
监听ServletRequest对象的创建与销毁
4. ServletContextAttributeListener
监听ServletContext中属性的创建、修改和销毁
5. HttpSessionAttributeListener
监听HttpSession中属性的创建、修改和销毁
6. ServletRequestAttributeListener
监听ServletRequest中属性的创建、修改和销毁
7. HttpSessionBindingListener
监听某个对象在Session域中的创建与移除
8. HttpSessionActivationListener
监听某个对象在Session中的序列化与反序列化。
Listener 监听器的使用步骤:
- 实现八大监听器中相应一种,重写相应的方法
- 到 web.xml 中去配置 Listener
web.xml 中的配置:
<listener>
<listener-class>com.demo.listener.HelloListener</listener-class>
</listener>