Servlet过滤器工作过程
jopen
10年前
Servlet过滤器工作过程
新建一个javaweb项目。如下的web.xml配置。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <filter> <filter-name>PerformanceFilter</filter-name> <filter-class>com.lyx.filter.PerformanceFilter</filter-class> </filter> <filter> <filter-name>PerformanceFilter2</filter-name> <filter-class>com.lyx.filter.PerformanceFilter2</filter-class> </filter> <filter-mapping> <filter-name>PerformanceFilter</filter-name> <url-pattern>/PerformanceServlet</url-pattern> </filter-mapping> <filter-mapping> <filter-name>PerformanceFilter2</filter-name> <url-pattern>/PerformanceServlet</url-pattern> </filter-mapping> <servlet> <servlet-name>PerformanceServlet</servlet-name> <servlet-class>com.lyx.servlet.PerformanceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>PerformanceServlet</servlet-name> <url-pattern>/PerformanceServlet</url-pattern> </servlet-mapping> </web-app>
有两个filter,其中PerformanceFilter如下:
package com.lyx.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class PerformanceFilter implements Filter { private FilterConfig config; public PerformanceFilter() { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; System.out.println("=======filter1 start=====" + httpServletRequest.getRequestURI()); chain.doFilter(request, response); //把处理权交给下一个filter System.out.println("=======filter1 end=======" + httpServletRequest.getRequestURI()); } @Override public void init(FilterConfig fConfig) throws ServletException { this.config = fConfig; } }
PerformanceFilter2如下:
package com.lyx.filter; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * 在这个filter中统计请求到响应的时间 */ public class PerformanceFilter2 implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { HttpServletRequest httpServletRequest = (HttpServletRequest) req; System.out.println("=======filter2 start=====" + httpServletRequest.getRequestURI()); long start = System.currentTimeMillis(); chain.doFilter(req, resp); long end = System.currentTimeMillis(); System.out.println("total=" + (end - start)); System.out.println("=======filter2 end=======" + httpServletRequest.getRequestURI()); } public void init(FilterConfig config) throws ServletException { } }
其中servlet如下:
package com.lyx.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "PerformanceServlet", urlPatterns = {"/PerformanceServlet"}, loadOnStartup = 1) public class PerformanceServlet extends HttpServlet { private static final long serialVersionUID = 1L; public PerformanceServlet() { super(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String name = request.getParameter("name"); out.println("<html>"); out.println("<head>"); out.println("<title>Hello Servlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1> Hello! " + name + " !</h1>"); out.println("</body>"); out.println("</html>"); out.close(); } }
ok,启动web程序,查看后台打印情况:
=======filter1 start=====/PerformanceServlet
=======filter2 start=====/PerformanceServlet
total=2
=======filter2 end=======/PerformanceServlet
=======filter1 end=======/PerformanceServlet
很直观的反映了filter的执行过程,尤其当多个filter匹配时。。。
总结多个filter的执行过程:
过滤器的执行流程了:执行第一个过滤器的chain.doFilter()之前的代码——>第二个过滤器的chain.doFilter()之前的代码——>……——>第n个过滤器的chain.doFilter()之前的代码——>所请求servlet的service()方法中的代码——>所请求servlet的doGet()或doPost()方法中的代码——>第n个过滤器的chain.doFilter()之后的代码——>……——>第二个过滤器的chain.doFilter()之后的代码——>第一个过滤器的chain.doFilter()之后的代码。
===END===
来自:http://my.oschina.net/xinxingegeya/blog/323763