filter是什么?
①. JavaWEB 的一个重要组件, 可以对发送到 Servlet 的请求进行拦截, 并对响应也进行拦截.
②. Filter 是实现了 Filter 接口的 Java 类
③. Filter 需要在 web.xml 文件中进行配置和映射
①. 创建一个 Filter 类: 实现 Filter 接口
public class HelloFilter implements Filter
②. 在 web.xml 文件中配置并映射该 Filter.;其中 url-pattern 指定该 Filter 可以拦截哪些资源, 即可以通过哪些 url 访问到该 Filter(和servlet配置类似)
导入的包是:
1 import javax.servlet.*;
在web.xml中配置:
<!-- 注册 Filter --> <filter> <filter-name>filterTest</filter-name> <filter-class>com.servlet.sc.HelloFilter</filter-class> </filter> <!-- 映射 Filter --> <filter-mapping> <filter-name>filterTest</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping>
import javax.servlet.*; import java.io.IOException; public class HelloFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("请求通过了我"); } @Override public void destroy() { } }
①. Filter 接口:
public void init(FilterConfig filterConfig) throws ServletException {}
类似于 Servlet 的 init 方法. 在创建 Filter 对象(Filter 对象在 Servlet 容器加载当前 WEB 应用时即被创建)后, 立即被调用, 且只被调用一次. 该方法用于对当前的 Filter 进行初始化操作. Filter 实例是单例的.
FilterConfig 类似于 ServletConfig
可以在 web.xml 文件中配置当前 Filter 的初始化参数. 配置方式也和 Servlet 类似。
<filter> <filter-name>helloFilter</filter-name> <filter-class>com.servlet.sc.HelloFilter</filter-class> <init-param> <param-name>name</param-name> <param-value>root</param-value> </init-param> </filter>
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}
真正 Filter 的逻辑代码需要编写在该方法中. 每次拦截都会调用该方法.
FilterChain: Filter 链. 多个 Filter 可以构成一个 Filter 链.
- doFilter(ServletRequest request, ServletResponse response): 把请求传给 Filter 链的下一个 Filter,若当前 Filter 是 Filter 链的最后一个 Filter, 将把请求给到目标 Serlvet(或 JSP)
多个 Filter 拦截的顺序和 <filter-mapping> 配置的顺序有关, 靠前的先被调用.
public void destroy() {}
释放当前 Filter 所占用的资源的方法. 在 Filter 被销毁之前被调用, 且只被调用一次.
<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>/error.jsp</location> </error-page> <filter-mapping> <filter-name>errorFilter</filter-name> <url-pattern>/error.jsp</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
1). Servlet API 中提供了一个 HttpServletRequestWrapper 类来包装原始的 request 对象,HttpServletRequestWrapper 类实现了 HttpServletRequest 接口中的所有方法, 这些方法的内部实现都是仅仅调用了一下所包装的的 request 对象的对应方法
//包装类实现 ServletRequest 接口.
public class ServletRequestWrapper implements ServletRequest { //被包装的那个 ServletRequest 对象 private ServletRequest request; //构造器传入 ServletRequest 实现类对象 public ServletRequestWrapper(ServletRequest request) { if (request == null) { throw new IllegalArgumentException("Request cannot be null"); } this.request = request; } //具体实现 ServletRequest 的方法: 调用被包装的那个成员变量的方法实现。 public Object getAttribute(String name) { return this.request.getAttribute(name); } public Enumeration getAttributeNames() { return this.request.getAttributeNames(); } //... }
相类似 Servlet API 也提供了一个 HttpServletResponseWrapper 类来包装原始的 response 对象
2). 作用: 用于对 HttpServletRequest 或 HttpServletResponse 的某一个方法进行修改或增强.
public class MyHttpServletRequest extends HttpServletRequestWrapper{ public MyHttpServletRequest(HttpServletRequest request) { super(request); } @Override public String getParameter(String name) { String val = super.getParameter(name); if(val != null && val.contains(" fuck ")){ val = val.replace("fuck", "****"); } return val; } }
3). 使用: 在 Filter 中, 利用 MyHttpServletRequest 替换传入的 HttpServletRequest
HttpServletRequest req = new MyHttpServletRequest(request);
filterChain.doFilter(req, response);
此时到达目标 Servlet 或 JSP 的 HttpServletRequest 实际上是 MyHttpServletRequest
原文:https://www.cnblogs.com/lzghyh/p/14052797.html