Servlet & JSP - Filter

过滤器可以对用户的请求拦截,进行预处理操作,接着将请求交给 Servlet 处理并生成响应,最后再对响应拦截,进行后处理操作。过滤器应用的场景有:用户登录、加密解密、会话校验等。

 

Filter API

过滤器必须继承 javax.servlet.Filter 接口。Filter 接口暴露三个生命周期方法:init、doFilter 和 destroy。

init:  当容器将过滤器引入服务的时候(通常是应用启动的时候),init 方法会被调用。Servlet 容器调用 init 方法时会传入一个 javax.servlet.FilterConfig 参数。FilterConfig 包含了过滤器的配置信息,如过滤器的名称、初始化参数、上下文环境等。

doFilter: 当过滤器关联的资源被请求时,doFilter 方法会被调用。doFilter 方法接收三个参数:ServletRequest、ServletResponse 和 FilterChain。ServletRequest 和 ServletResponse 是被拦截的请求和响应对象,我们可以对其做一些处理,如对请求设置属性或者在响应添加 HTTP 首部,甚至是使用装饰器来改变请求和响应的行为。调用 FilterChain 的 doFilter 方法将请求和响应传递至过滤器链的下一个过滤器或目标资源。在 filterChain.doFilter(request, response) 方法调用之前的操作是预处理,在  filterChain.doFilter(request, response) 方法调用之后的操作是后处理。

destroy: 当容器将过滤器移出服务的时候(通常是应用停止的时候),destroy 方法会被调用。

 

配置过滤器

1. 使用部署描述符配置:

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.huey.hello.filters.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2. 在 Servlet3.0 可以使用 @WebFilter 注解配置:

@WebFilter(filterName = "myFilter", urlPatterns = {"/*"})
public class MyFilter implements Filter {
    // ...
}

 

过滤器的作用顺序

当多个过滤器作用在同一资源时,过滤器的作用顺序由其在部署描述符中的声明顺序决定,使用 @WebFilter 注解无法指定作用顺序。假设有 Filter1 和 Filter2 作用在同一个资源,且 Filter1 在 Filter2 之前声明,那么作用顺序为:Filter1 的预处理 ---> Filter2 的预处理 ---> 目标资源的处理 ---> Filter2 的后处理 ---> Filter1 的后处理。

 

应用示例

package com.huey.hello.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;

import com.huey.hello.wrapper.CharsetServletRequestWrapper;

/**
 * 使用注解配置 Filter
 * urlPatterns 配置关联的目标资源
 * initParams 配置初始参数
 */
@WebFilter(filterName="charsetFilter", urlPatterns = {"/*"}, 
        initParams = {
                @WebInitParam(name = "oldCharset", value = "ISO-8859-1"),
                @WebInitParam(name = "newCharset", value = "UTF-8"),
        })
public class CharsetFilter implements Filter {

    private String oldCharset;
    private String newCharset;
            
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        oldCharset = filterConfig.getInitParameter("oldCharset");
        newCharset = filterConfig.getInitParameter("newCharset");
    }
    
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding(newCharset);
        response.setContentType("text/plain;charset=" + newCharset);
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        CharsetServletRequestWrapper requestWrapper = new CharsetServletRequestWrapper(httpRequest, oldCharset, newCharset);         
        chain.doFilter(requestWrapper, response);
    }

}

 

posted on 2016-05-10 15:11  huey2672  阅读(255)  评论(0编辑  收藏  举报