过滤器(Filter)是能够为请求和响应的header和内容进行操作的一种特殊的web组件。特殊之处在于其本身并不直接生成web响应,而是拦截过滤web请求和响应。下面直接用代码说明Servlet过滤器
**
* 完成请求的拦截,以及资源的统一管理功能
* 定义
*
* @author Song X.
* @date 2020/02/16
*/
public class MyFilter1 implements Filter {
/**
* 完成Filter的初始化功能,服务器开启时就执行
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("我是filter1 init");
}
/**
* 完成Filter的功能,每执行Filter对应的Servlet时执行一次
* @param servletRequest
* @param servletResponse
* @param filterChain filterChain用于调用过滤器链中的一系列过滤器,这是责任链设计模式的具体体现
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//开始执行filter
System.out.println("我是filter1逻辑处理");
//为过滤的Servlet设置统一编码格式
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("gbk");
//调用下一个过滤器,若没有下一个过滤器则执行对应的Servlet
filterChain.doFilter(servletRequest,servletResponse);
//Servlet处理完后才会输出这句话
System.out.println("filter1处理完成");
}
/**
* 完成Filter的销毁功能,在关闭服务器时执行
*/
@Override
public void destroy() {
System.out.println("我是filter1销毁功能");
}
}
public class MyFilter2 implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("我是filter2 init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws ServletException, IOException {
System.out.println("我是filter2逻辑处理");
filterChain.doFilter(req, resp);
System.out.println("filter2处理完成");
}
@Override
public void destroy() {
System.out.println("我是filter2销毁功能");
}
}
public class FilterServlet1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是FilterServlet1");
response.getWriter().write("我是FilterServlet1");
}
}
public class FilterServlet2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是FilterServlet2");
response.getWriter().write("我是FilterServlet2");
}
}
<!--有多个针对同一Servlet的过滤器时,过滤器链的顺序按照web.xml中配置Filter的顺序
这里针对所有Servlet,Filter的过滤顺序是先MyFilter1,后MyFilter2
url-pattern表示要过滤的Servlet的url-pattern-->
<filter>
<filter-name>MyFilter1</filter-name>
<filter-class>home.frank.filterProject.MyFilter1</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>MyFilter2</filter-name>
<filter-class>home.frank.filterProject.MyFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Servlet监听器可以理解为一直观察Servlet的监视器,当Servlet发生一些行为时,监听器作出一些必要的响应。实际上所有监听器都是这样。比如,有监听ServletContext的ServletContext,有监听session的HttpSessionListener,有监听request的ServletRequestListener。
下面以Request为例,代码演示说明各监听器
public class ListenerServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("listenerServlet逻辑处理");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("gbk");
request.setAttribute("listen","listen");
request.removeAttribute("listen");
response.getWriter().write("listen study");
}
}
/**
* 监听器:主要用于监听作用域对象的创建,销毁,以及属性设置,可以添加一些公共属性设置,做逻辑判断
*
* 主要监听三种:
* Request:主要有两个监听接口: ServletRequestListener, ServletRequestAttributeListener
* ServletRequestListener: 监听request对象的创建和销毁
* ServletRequestAttributeListener:监听request作用域属性的添加删除和修改
*
* ServletContext:主要有两个监听接口: ServletContextListener, ServletContextAttributeListener
* ServletContextListener: 监听ServletContext对象的创建和销毁
* ServletContextAttributeListener:监听ServletContext作用域属性的添加删除和修改
*
* Session:主要有四个监听接口: HttpSessionListener, HttpSessionAttributeListener, HttpSessionActivationListener, HttpSessionBindingListener
* HttpSessionListener:监听Session对象的创建和销毁
* HttpSessionAttributeListener:监听Session对象作用域属性的添加删除和修改
* HttpSessionActivationListener:监听Session对象中数据从内存中持久化要硬盘,或从硬盘读入数据
* HttpSessionBindingListener:与HttpSessionListener类似,只不过HttpSessionBindingListener的使用需要实例化这么个监听器对象,
* 然后以session.setAttribute的方式绑定到一个session上实行监控。也就是说HttpSessionListener是对所有session的监控,
* 而HttpSessionBindingListener可以实现一对一的监控
*
* 下面代码以request为例,简单演示监听器的作用
*
* @author Song X.
* @date 2020/02/16
*/
public class MyListen implements ServletRequestListener, ServletRequestAttributeListener {
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象被创建" + System.currentTimeMillis());
}
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println("request对象被销毁" + System.currentTimeMillis());
}
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("向request作用域中添加数据");
System.out.println(servletRequestAttributeEvent.getName());
System.out.println(servletRequestAttributeEvent.getValue());
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("向request作用域删除数据");
System.out.println(servletRequestAttributeEvent.getName());
System.out.println(servletRequestAttributeEvent.getValue());
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
System.out.println("向request作用域替换数据");
System.out.println(servletRequestAttributeEvent.getName());
System.out.println(servletRequestAttributeEvent.getValue());
}
}
<servlet>
<servlet-name>ListenerServlet</servlet-name>
<servlet-class>home.frank.listenerProject.ListenerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListenerServlet</servlet-name>
<url-pattern>/listen</url-pattern>
</servlet-mapping>
<listener>
<listener-class>home.frank.listenerProject.MyListen</listener-class>
</listener>
到此为止,Servlet全部回顾完毕。Servlet虽然现在在开发中已经很少使用了,但是了解它的原理,对学习Java EE框架底层源码原理,有很大的帮助。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/20598.html