Hao's Blog
利用Filter解决全站编码问题(复习)

在不使用filter之前,要想处理编码问题我们需要依据不同的请求方式,做出不同的编码处理

例如

1.一个请求方式为post的表单传入了servlet,需要设置编码格式对传入参数重新编码

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");  //需要设置编码格式对传入参数重新编码
        response.setContentType("text/html;charset=utf-8");
}

2.而如果为get请求,那么步骤就更加繁琐,我们需要先将传入的表单数据先解码然后在编码

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String value = request.getParameter("name");
        String newValue = new String(value.getBytes("iso-8859-1"), "utf-8");
        doPost(request, response);
}

综上所述,如果我们像以上办法一样处理编码问题也是可以的,但是可以看出是很不方便的,每新增一个servlet都要写一遍重复的设置编码的内容,特别是get请求,如果传入的参数过多,就需要写很多解码转码的重复代码,很不方便,所以我们就要使用filter(过滤器).

Filter能干啥

可以对Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后处理。使用Filter 的完整流程:Filter 对用户请求进行预处理,接着将请求交给Servlet 进行处理并生成响应,最后Filter 再对服务器响应进行后处理。

filter咋用

使用filter就需要实现javax.servlet.Filter接口,该接口就三个方法需要实现

以处理编码的filter为例,其中get请求我们需要重写它的请求

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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CharsetEncodingFilter implements Filter {
    private FilterConfig fconfig;

    public void destroy() {

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        //编码从web.xml初始化参数中获取,没有配置就默认为utf-8
        String encoding = fconfig.getInitParameter("CharsetEncoding");
        if(encoding == null '' encoding.trim().isEmpty()) {
            encoding = "UTF-8";
        }

        if(request.getMethod().equalsIgnoreCase("GET")) {
            EncodingRequest er = new EncodingRequest(request, encoding); //使用重写之后的request
            chain.doFilter(er, response);
        } else if(request.getMethod().equalsIgnoreCase("POST")) {
            req.setCharacterEncoding(encoding);
            chain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig filtercfg) throws ServletException {
        this.fconfig = filtercfg;
    }

}

重写request实现HttpServletRequestWrapper类,其目的就是为了重写其中的getParameter()方法

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class EncodingRequest extends HttpServletRequestWrapper {
    private HttpServletRequest req;
    private String charsetEncoding;

    public EncodingRequest(HttpServletRequest request, String encoding) {
        super(request);
        this.req = request;
        this.charsetEncoding = encoding;
    }

    public String getParameter(String name) {
        try {
            String value = req.getParameter(name);
            return new String(value.getBytes("iso-8859-1"), charsetEncoding); //java编码为iso-8859-1
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}

filter和servlet一样,还需要在web.xml中注册才能使用,而配置的方法也和servlet大同小异

<filter>
<filter-name>CharsetEncodingFilter</filter-name>
<filter-class>com.infosys.filter.CharsetEncodingFilter</filter-class>
<init-param>
    <param-name>CharsetEncoding</param-name> ---初始化参数,可以再filter初始化的使用读取
    <param-value>UTF-8</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>