CharacterEncodingFilter

转载 2015年11月17日 20:21:43

我的第一篇正式BLOG就写点简单的东西吧,记录一下CharacterEncodingFilter这个类的使用和作用。
http://blog.csdn.net/heidan2006/article/details/3075730
很简单很实用的一个过滤器,当前台JSP页面和JAVA代码中使用了不同的字符集进行编码的时候就会出现表单提交的数据或者上传/下载中文名称文件出现乱码的问题,那这个类就可以出场了。

    从名字就可以看出来它是个过滤器了,所以就要想配置普通过滤器那样配置到web.xml中去了,配置方式如下:

    <filter>
            <filter-name>encodingFilter</filter-name>
                <filter-class>
                    org.springframework.web.filter.CharacterEncodingFilter
                </filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>false</param-value>
           </init-param>
    </filter>
    <filter-mapping>
            <filter-name>encodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
   </filter-mapping>
    和普通过滤器配置没什么区别,就是多了两个初始化参数,两个参数的作用分别是:

encoding----->用来指定一个具体的字符集

forceEncoding------->Spring的早期版本这个参数作用很单一,当request中已经被指定了一个字符集的时候是否再将用endcoding对应的字符集设置到request中去。举个例子来说明,假如说过滤器就像上面那样被配置到web.xml了,当请求被提交之后,过滤器会判断request.getCharacterEncoding()是否为null,如果是null那么就会进行request.setCharacterEncoding("UTF-8")的操作,如果不是null那么过滤器什么也不会做。

不过Spring目前得版本这个类的代码已经被重构了,代码更加“漂亮”了,这个参数的作用也发生了细微的改变。

为了加深印象从源码来分析一下这个参数的变化。

首先,说明 一下CharacterEncodingFilter是继承OncePerRequestFilter抽象类而来的,OncePerRequestFilter实现了doFilter方法:

public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
………..
………..
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {
filterChain.doFilter(request, response);
}
else {
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {
doFilterInternal(httpRequest, httpResponse, filterChain);
}
finally {
request.removeAttribute(alreadyFilteredAttributeName);
}
}
}
public static final String ALREADY_FILTERED_SUFFIX = “.FILTERED”;(在OncePerRequestFilter中定义的常量)
说明:

  1. getAlreadyFilteredAttributeName()方法返回的字符串是=”我们给filter配置的名字+ALREADY_FILTERED_SUFFIX”,所以request请求第一次到达过滤器的时候request.getAttribute(alreadyFilteredAttributeName) 值一定是null ,shouldNotFilter(httpRequest)方法默认实现始终返回false(这个方法也可以在子类中进行扩展);

  2. 当request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE)之后就会执行doFilterInternal(httpRequest, httpResponse, filterChain);方法了,doFilterInternal这里是个抽象方法,它是在子类CharacterEncodingFilter中被实现的,实现如下:

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
    throws ServletException, IOException {
    if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
    request.setCharacterEncoding(this.encoding);
    if (this.forceEncoding && responseSetCharacterEncodingAvailable) {
    response.setCharacterEncoding(this.encoding);
    }
    }
    filterChain.doFilter(request, response);
    }
    private final static boolean responseSetCharacterEncodingAvailable = ClassUtils.hasMethod(
    HttpServletResponse.class, “setCharacterEncoding”, new Class[] {String.class});
    说明:

  3. 静态常量responseSetCharacterEncodingAvailable 是通过反射来判断response是否有setCharacterEncoding方法,返回值应该都是true.

  4. this.encoding != null :当encoding初始化参数被指定时条件满足。

  5. (this.forceEncoding || request.getCharacterEncoding() == null )==true:当forceEncoding初始化参数设置为true或者request已经被指定了一个字符编码的时候条件满足。

如果没记得错,Spring早期版本这个方法得实现应该是:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (this.forceEncoding || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(this.encoding);
}
filterChain.doFilter(request, response);
}
参数forceEncoding的作用很明显了吧!以前只是对request字符编码起作用,现在如果将forceEncoding设为true也会影响到response中的字符编码,通常这个是我们不希望的。

总结:

  1. OncePerRequestFilter这个抽象过滤器很好的实现了对每个request只执行一次过滤操作,如果有类似的需求可以继承该类并实现doFilterInternal方法来完成。

  2. CharacterEncodingFilter类可以通过简单配置来帮我们实现字符集转换的功能。另外多说一句,如果采用Struts2.0的MVC框架我个人感觉中文问题已经不是问题了,可以通过配置struts.i18n.encoding常量来实现统一字符编码。

说明:所写内容纯属个人理解和认识,如有理解偏差希望有热心的朋友可以指出,如有描述有含糊不清的地方希望可以和你得到沟通和交流!

CharacterEncodingFilter类的学习 .doc

  • 2009年07月23日 10:45
  • 32KB
  • 下载

web.xml中配置CharacterEncodingFilter编码过滤器的原理

在web.xml文件中,我们经常可以看到配置的统一编码过滤器,他继承了OncePerRequestFilter,而OncePerRequestFilter继承自GenericFilterBean,Ge...
  • uhgagnu
  • uhgagnu
  • 2017年03月01日 13:28
  • 2128

org.springframework.web.filter.CharacterEncodingFilter作用

org.springframework.web.filter.CharacterEncodingFilter作用

org.springframework.web.filter.CharacterEncodingFilter详解

很简单很实用的一个过滤器,当前台JSP页面和JAVA代码中使用了不同的字符集进行编码的时候就会出现表单提交的数据或者上传/下载中文名称文件出现乱码的问题,那这个类就可以出场了。 web.xml中配置...

详解Spring中的CharacterEncodingFilter--forceEncoding为true在java代码中设置失效--html设置编码无效?不知真假

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处、作者信息和本声明。否则将追究法律责任。 本文链接:http://blog.sina.com.cn/s/blog_92b93d6f0...

Spring MVC过滤器之CharacterEncodingFilter(字符集过滤器)

我们为了处理项目中的乱码问题,可以在Spring MVC中设置字符集过滤器:CharacterEncodingFilter。...

如何防止字符乱码:CharacterEncodingFilter的使用

==================== CharacterEncodingFilter.java ====================   packageblog.filter; i...

org.springframework.web.filter.CharacterEncodingFilter

感谢:http://blog.csdn.net/heidan2006/article/details/3075730 很简单很实用的一个过滤器,当前台JSP页面和JAVA代码中使用了不同...

Spring字符集过滤器CharacterEncodingFilter

Spring中的字符集过滤器可以很方便的为我们解决项目中出现的中文乱码问题,而且使用方法也很简单,只需要在web.xml文件中配置一下该过滤器,设置两个重要的参数(encoding和forceEnco...
  • GDUFZXP
  • GDUFZXP
  • 2013年08月19日 16:59
  • 19308
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CharacterEncodingFilter
举报原因:
原因补充:

(最多只允许输入30个字)