`

CharacterEncodingFilter类的学习(转)

阅读更多
     我的第一篇正式BLOG就写点简单的东西吧,记录一下CharacterEncodingFilter这个类的使用和作用。

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

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

   1.         <filter>
   2.                 <filter-name>encodingFilter</filter-name>
   3.                     <filter-class>
   4.                         org.springframework.web.filter.CharacterEncodingFilter
   5.                     </filter-class>
   6.                 <init-param>
   7.                     <param-name>encoding</param-name>
   8.                     <param-value>UTF-8</param-value>
   9.                 </init-param>
  10.                 <init-param>
  11.                     <param-name>forceEncoding</param-name>
  12.                     <param-value>false</param-value>
  13.                </init-param>
  14.         </filter>
  15.
  16.         <filter-mapping>
  17.                 <filter-name>encodingFilter</filter-name>
  18.                 <url-pattern>/*</url-pattern>
  19.        </filter-mapping>
20.

        和普通过滤器配置没什么区别,就是多了两个初始化参数,两个参数的作用分别是:

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

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

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

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

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

   1.  public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
   2.    throws ServletException, IOException {
   3.
   4.          ...........
   5.
   6.          ...........
   7.
   8.       String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
   9.       if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {
  10.
  11.            filterChain.doFilter(request, response);
  12.       }
  13.       else {
  14.            request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
  15.        try {
  16.             doFilterInternal(httpRequest, httpResponse, filterChain);
  17.            }
  18.        finally {
  19.
  20.             request.removeAttribute(alreadyFilteredAttributeName);
  21.            }
  22.       }
  23.  }
  24.
  25. public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";(在OncePerRequestFilter中定义的常量)
26.

说明:

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中被实现的,实现如下:

   1.  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
   2.    throws ServletException, IOException {
   3.
   4.          if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
   5.                 request.setCharacterEncoding(this.encoding);
   6.                if (this.forceEncoding && responseSetCharacterEncodingAvailable) {
   7.                     response.setCharacterEncoding(this.encoding);
   8.                    }
   9.               }
  10.               filterChain.doFilter(request, response);
  11.   }
  12.
  13. private final static boolean responseSetCharacterEncodingAvailable = ClassUtils.hasMethod(
  14.    HttpServletResponse.class, "setCharacterEncoding", new Class[] {String.class});
15.

说明:

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

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

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

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

   1.  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
   2.    throws ServletException, IOException {
   3.
   4.          if (this.forceEncoding || request.getCharacterEncoding() == null) {
   5.                    request.setCharacterEncoding(this.encoding);
   6.               }
   7.               filterChain.doFilter(request, response);
   8.   }
9.

参数forceEncoding的作用很明显了吧!以前只是对request字符编码起作用,现在如果将forceEncoding设为true也会影响到response中的字符编码,通常这个是我们不希望的。

总结:

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

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

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

相关推荐

    CharacterEncodingFilter类的学习 .doc

    CharacterEncodingFilter类的学习CharacterEncodingFilter类的学习

    字符编码工具类CharacterEncodingFilter.java

    字符编码工具类CharacterEncodingFilter.java 字符编码工具类CharacterEncodingFilter.java 字符编码工具类CharacterEncodingFilter.java

    CharacterEncodingFilter.java

    CharacterEncodingFilter.java

    字符过滤器

    &lt;display-name&gt;CharacterEncodingFilter &lt;filter-name&gt;CharacterEncodingFilter &lt;filter-class&gt;CharacterEncodingFilter &lt;filter-name&gt;CharacterEncodingFilter &lt;url-pattern&gt;/* &lt;/web-app&gt;

    JSP存到数据库乱码解决办法

    &lt;filter-name&gt;CharacterEncodingFilter &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter &lt;param-name&gt;encoding &lt;param-value&gt;UTF-8 &lt;param-name&gt;forceEncoding ...

    乱码解决问题

    CharacterEncodingFilter.java 解决乱码。

    log4j.properties

    解决警告:log4j:WARN No appenders could be found for logger (org.springframework.web.filter.CharacterEncodingFilter).

    sshz中文乱码解决方法

    org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class&gt; &lt;init-param&gt; &lt;param-name&gt;encoding&lt;/param-name&gt; &lt;param-value&gt;GBK&lt;/param-value&gt; &lt;/init-param&gt; &lt;init-param&gt; &lt;param-name&gt;...

    java解决中文乱码问题

    当时因为学习忙没去关注这个,等我闲了,那个朋友不弄这个,问他,他也不说不大清楚,最后自己对这个学习也不了了之了。 Java 中文乱码问题的解决方法 1. 使用 UTF-8 编码 在 Java 中,默认的编码方式是 UNICODE...

    关于SSH中文乱码的一个小总结.doc

    Spring提供了一个CharacterEncodingFilter来解决中文乱码问题,该过滤器可以在web.xml中进行配置。 配置方法: &lt;filter-name&gt;encodingFilter &lt;filter-class&gt;org.springframework.web.filter....

    ssh(structs,spring,hibernate)框架中的上传下载

     需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...

    spring配置编码格式

    org.springframework.web.filter.CharacterEncodingFilter &lt;param-name&gt;encoding &lt;param-value&gt;UTF-8 &lt;filter-name&gt;setCharacterEncoding &lt;url-pattern&gt;/* &lt;!-- 配置编码格式 end --&gt;

    聊天室程序下载

    public class CharacterEncodingFilter implements Filter{ protected String encoding = null; protected FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ...

    java servlet 监听器

    * 从HttpServletRequestWrapper包装类中取出我们要进行转码的request; * * @return */ public HttpServletRequest getHttpServletRequest() { return (HttpServletRequest) super.getRequest(); ...

    SSMM-Demo:实践出真知,相对于SSM-Demo项目,本项目是一个基于SSMM(SpringMVC + Spring + Mybatis + Redis + Maven)的练手Demo

    SSMM演示 ...Demo,是在SSM-Demo项目的基础上修改,调整而来,主要涉及以下几项技术及知识点: 使用SpringMVC作MVC控制器;...使用Mybatis作持久层(ORM)框架:以面向对象的方式对PO类的操作映射成为对应的持久化操作;

    web配置文件.txt

    &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter &lt;param-name&gt;encoding &lt;param-value&gt;UTF-8 &lt;param-name&gt;forceEncoding &lt;param-value&gt;true &lt;filter-name&gt;encodingFilter ...

    apache-tomcat-7.0.69.zip

    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java...

    JavaWeb乱码过滤器.zip

     &lt;filter-class&gt;com.github.zhanhb.filter.CharacterEncodingFilter&lt;/filter-class&gt;    &lt;description&gt;Encoding for content and query string, default UTF-8.  &lt;param-name&gt;characterEncoding  ...

    JQuery发送ajax请求时中文乱码问题解决

    这篇文章主要介绍了JQuery发送ajax请求时中文乱码问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 先排除项目故障: 1.web.xml中是否配置了字符拦截器...

    myeclipse中文处理

    -- 中文过滤器start --&gt; &lt;filter&gt;&lt;br&gt; &lt;filter-name&gt;Encoding&lt;/filter-name&gt;&lt;br&gt; &lt;filter-class&gt;&lt;br&gt; org.springframework.web.filter.CharacterEncodingFilter &lt;/filter-class&gt;&lt;br&gt; &lt;init-param&gt;&lt;br&gt;...

Global site tag (gtag.js) - Google Analytics