目录
什么是Filter?
Filter是由Servlet容器进行调用,对 Servlet容器请求java服务端程序(调用资源:JSP,Servlet,静态HTML),java服务端程序响应Servlet容器进行拦截,对服务端程序进行响应处理的前后实现一些特殊的功能,需要在web.xml文件中进行配置,可以拦截JSP,Servlet,静态图片,静态文件,静态HTML等
Filter的基本工作原理
对Servlet容器发送给服务端程序的请求和服务端程序返回给Servlet容器的响应进行拦截
可以决定是否将请求继续传递给下去,以及对请求和响应的信息是否进行修改Filter执行的顺序与配置的<FilterMapping>一致
Filter的HelloWorld
1.新建一个Servlet,并配置
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet..........hello"); resp.getWriter().print("HELLO"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
<servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.tony.web.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
2.新建一个Filter,并配置
public class HelloFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("HelloFilter init..."); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("HelloFilter before doFilter..."); filterChain.doFilter(servletRequest, servletResponse); System.out.println("HelloFilter after doFilter..."); } @Override public void destroy() { System.out.println("HelloFilter destroy..."); } }
<filter> <filter-name>helloFilter</filter-name> <filter-class>com.tony.web.filter.HelloFilter</filter-class> </filter> <filter-mapping> <filter-name>helloFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3.运行测试&结果
HelloFilter before doFilter... doGet..........hello HelloFilter after doFilter...
Filter接口
void init(FilterConfig var1) throws ServletException;
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
void destroy();
FilterConfig接口
String getFilterName();
ServletContext getServletContext();
String getInitParameter(String var1);
Enumeration<String> getInitParameterNames();
FilterChain接口
//Filter链,一个以上的Filter构成
//如果当前Filter不是Filter链中的最后一个Filter,则把请求传给Filter链中的下一个Filter
//如果当前Filter是Filter链中的最后一个Filter,则把请求传给目标
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
配置dispatcher节点
<dispatcher>节点
指定过滤器所拦截的资源被Servlet容器调用的方式,可以是
REQUEST,INCLUDE,FORWARD,ERROR之一
默认REQUEST,可以设置多个<dispatcher>子元素用来指定Filter对资源的多种调用方式进行拦截
①. REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
通过 GET 或 POST 请求直接访问。
②. FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
或 <jsp:forward page="/..." /> 或 通过 page 指令的 errorPage 转发页面. <%@ page errorPage="test.jsp" %>
②. INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
或 <jsp:include file="/..." />
④. ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
在 web.xml 文件中通过 error-page 节点进行声明:
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/test.jsp</location>
</error-page>
<filter-mapping>
<filter-name>secondFilter</filter-name>
<url-pattern>/test.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
案例
- 禁用浏览器缓存案例
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
- 字符编码过滤器
- 检查用户是否登陆过的过滤器
- 权限管理