Spring 字符集过滤器CharacterEncodingFilter

1.CharacterEncodingFilter源码解析

public class CharacterEncodingFilter extends OncePerRequestFilter {
    private String encoding;
    private boolean forceRequestEncoding;
    private boolean forceResponseEncoding;

    public CharacterEncodingFilter() {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
    }

    public CharacterEncodingFilter(String encoding) {
        this(encoding, false);
    }

    public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
        this(encoding, forceEncoding, forceEncoding);
    }

    public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceRequestEncoding = forceRequestEncoding;
        this.forceResponseEncoding = forceResponseEncoding;
    }

    //...

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        if (encoding != null) {
            if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                request.setCharacterEncoding(encoding);
            }

            if (this.isForceResponseEncoding()) {
                response.setCharacterEncoding(encoding);
            }
        }

        filterChain.doFilter(request, response);
    }
}

通过源码,我们知道,CharacterEncodingFilter构造函数最多可以指定三个参数: encoding, forceRequestEncoding, forceResponseEncoding``。

1.forceRequestEncoding强制指定:request.setCharacterEncoding("XXXX");

  1. forceResponseEncoding强制指定: response.setCharacterEncoding(“XXXX”);
    强制ServletResponse的编码格式和ServletRequest的编码格式一样。
@RequestMapping(value="XXXXX")  
public void XXXXX(User user,HttpServletRequest req,HttpServletResponse resp) throws UnsupportedEncodingException  
{  
       resp.setCharacterEncoding("UTF-8");  
       req.setCharacterEncoding("UTF-8");  
      //......  
}  

因此,在请求处理的过程中我们可以不用考虑编码方面的问题,上面两句代码可以省略,编码统一交给Spring过滤器去处理,我们可以专心处理我们的业务逻辑代码。


2.CharacterEncodingFilter对GET方法参数无效

不妨看看CharacterEncodingFilter内的实现 doFilterInternal该方法调用
request.setCharacterEncoding(this.encoding);

而该方法的说明
Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().

只对body起作用


3.CharacterEncodingFilter 要是第一个执行的filter

整个web应用里,这个filter的顺序必须是第一个,否则还是会出现乱码问题。这是因为:
request对象的parameter并不是一开始就解析的,它是等你第一次调用getParameter获得请求参数有关的方法的时候才解析的。paramter一旦被解析过一次,那就不会再次被解析。

如果在CharacterEncodingFilter之前有另外一个filter,而这个filter调用了getParameter方法,那么就有可能使用错误的encoding来解析,从而造成乱码问题。


4.response中setCharacterEncoding和setContentType的区别

setCharacterEncoding只是设置字符的编码方式
setContentType除了可以设置字符的编码方式还能设置文档内容的类型

response.setContentType("text/html;charset=utf-8");
等于
response.setHeader("content-type", "text/html;charset=utf-8");
等于
response.setHeader("content-type", "text/html");
response.setCharacterEncoding("utf-8");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章