Servlet过滤器工作过程
需注意,Filter不是一个Servlet,它不能产生一个response,它能够在一个request到达Servlet之前预处理request,也可以在离开Servlet时处理response。
将多个过滤器组成过滤器链,每个过滤器在应用程序中执行一个任务,这样有助于确保它们的模块性和复用性。
新建一个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=======
转载于:https://my.oschina.net/xinxingegeya/blog/323763