Filter过滤器

Filter解决请求乱码

Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下filter的doFilter方法。

应用举例:

批量设置请求编码


public class EncodingFilter implements Filter {  
  
    private String encoding = null;  
  
    public void destroy() {  
        encoding = null;  
    }  
  
    public void doFilter(ServletRequest request, ServletResponse response,  
            FilterChain chain) throws IOException, ServletException {  
        String encoding = getEncoding();  
        if (encoding == null){  
            encoding = "gb2312";  
        }  
        request.setCharacterEncoding(encoding);// 在请求里设置上指定的编码  
        chain.doFilter(request, response);  //通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源
    }  
  
    public void init(FilterConfig filterConfig) throws ServletException {  
        this.encoding = filterConfig.getInitParameter("encoding");  
    }  
  
    private String getEncoding() {  
        return this.encoding;  
    }  
  
}  

xml配置代码

<filter>  
    <filter-name>EncodingFilter</filter-name>  
    <filter-class>com.logcd.filter.EncodingFilter</filter-class>  
    <init-param>  
       <param-name>encoding</param-name>  
       <param-value>gb2312</param-value>  
    </init-param>  
</filter>  
  
<filter-mapping>  
   <filter-name>EncodingFilter</filter-name>  
   <url-pattern>/*</url-pattern>  
</filter-mapping>  

如上的代码完成的功能为,无论进入那个页面,都要先执行EncodingFilter类的dofilter方法设置字符集,其中,doFilter()方法类似于Servlet接口的service()方法。当客户端请求目标资源的时候,容器就会调用与这个目标资源相关联的过滤器的doFilter()方法。

参数 request, response 为web 容器或 Filter 链的上一个 Filter 传递过来的请求和相应对象;参数 chain 代表当前 Filter 链的对象。

对于FilterChain接口,代表当前Filter链的对象。由容器实现,容器将其实例作为参数传入过滤器对象的doFilter()方法中。

过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器,或者目标Servlet 程序去处理,也可以直接向客户端返回响应信息,或者利用RequestDispatcher的forward()和include()方法,以及HttpServletResponse的sendRedirect()方法将请求转向到其他资源。

这个方法的请求和响应参数的类型是 ServletRequest和ServletResponse,也就是说,过滤器的使用并不依赖于具体的协议。