`

转载 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.         <filter-mapping>
  16.                 <filter-name>encodingFilter</filter-name>
  17.                 <url-pattern>/*</url-pattern>
  18.        </filter-mapping>

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

    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.       String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
  6.       if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {
  7.            filterChain.doFilter(request, response);
  8.       }
  9.       else {
  10.            request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
  11.        try {
  12.             doFilterInternal(httpRequest, httpResponse, filterChain);
  13.            }
  14.        finally {
  15.             request.removeAttribute(alreadyFilteredAttributeName);
  16.            }
  17.       }
  18.  }
  19. 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中被实现的,实现如下:

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

说明:

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.          if (this.forceEncoding || request.getCharacterEncoding() == null) {
  4.                    request.setCharacterEncoding(this.encoding);
  5.               }
  6.               filterChain.doFilter(request, response);
  7.   }

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

总结:

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

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

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

分享到:
评论

相关推荐

    CharacterEncodingFilter类的学习 .doc

    `CharacterEncodingFilter` 类是 Spring 框架中用于处理 Web 应用程序字符编码问题的一个过滤器。在处理 HTTP 请求时,如果前端 JSP 页面和后端 Java 代码使用了不同的字符集,可能会导致数据乱码问题,尤其是在表单...

    字符编码工具类CharacterEncodingFilter.java

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

    CharacterEncodingFilter.java

    CharacterEncodingFilter.java

    学习了servlet之后,将servlet全部整合在一个工具类中

    在描述中提到的过滤器部分,可能包含自定义的过滤器实现,如`CharacterEncodingFilter`,用于统一设定请求和响应的编码为UTF-8。 2. **反射技术(Reflection)**:反射是Java的一个强大特性,允许程序在运行时检查...

    解决乱码问题工具类的使用.docx

    1. **CharacterEncodingFilter类**: 这个类实现了Servlet的`Filter`接口,主要目的是在请求进入和离开Servlet容器时进行字符编码的转换和设置。类中的`encode`变量用于存储字符编码的类型,默认值为"UTF-8"。在`...

    spring学习过程中遇到的问题和解决,eclipse使用

    ### Spring 学习过程中的关键知识点解析 #### 一、SpringMVC中文乱码问题及其解决方案 在开发基于SpringMVC的应用程序时,经常会遇到中文乱码的问题,尤其是在处理前端表单提交的数据时更为明显。这里提供两种有效...

    SpringMVC第一天学习代码

    在第一天的学习中,你将接触到一系列关键概念和技术,这些内容将帮助你理解和应用SpringMVC来构建动态网站。 首先,让我们从入门案例开始。SpringMVC的入门通常涉及创建一个DispatcherServlet,它是SpringMVC的前端...

    SpringMVC 学习总结

    3. 配置 web.xml,设置 DispatcherServlet 作为前端控制器,并定义 CharacterEncodingFilter 来确保请求编码统一。 4. 创建 springmvc-servlet.xml 配置文件,配置组件扫描、视图解析器、处理器映射器和处理器适配器...

    j2EE中个人学习,SSH经历作了总结希望对你有帮助

    总的来说,这个学习总结涵盖了j2EE开发中的关键概念,包括Struts的逻辑控制标签、Spring的依赖注入理念以及Web应用的基本配置。对于初学者来说,理解这些基本组件和它们如何协同工作是至关重要的,这将有助于构建更...

    乱码处理操作类

    在IT行业中,乱码问题是一个常见的困扰,尤其是在处理多语言环境或者进行数据传输时。"乱码处理操作类"指的是...对于这个"乱码处理操作类",我们可以通过查看源代码,学习其处理乱码的具体实现,以提升我们的编码技能。

    字符过滤器

    &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;

    appfuse学习笔记(三)解决乱码和菜单设置

    在本篇“appfuse学习笔记(三)解决乱码和菜单设置”中,我们将深入探讨在使用AppFuse框架时遇到的编码问题以及如何定制应用程序的菜单。AppFuse是一款开源项目,它提供了一个快速开发Web应用的基础,特别是对于Java...

    Spring 注解学习手札

    【Spring注解学习手札】 在现代Java Web开发中,Spring框架因其强大的功能和灵活性而备受推崇。Spring注解的引入极大地简化了配置文件,提高了开发效率。本篇将聚焦于Spring MVC中的注解,通过构建一个简单的Web...

    spring2.5学习PPT 传智博客

    - 利用CharacterEncodingFilter和OpenSessionInViewFilter解决编码问题。 通过以上内容的学习,开发者可以深入理解Spring 2.5的核心概念,掌握其在实际开发中的应用,从而提高工作效率和代码质量。

    SSH框架整合所需类class.txt

    ### SSH框架整合所需类知识点详解 #### 一、前言 在Java EE开发领域中,SSH(Struts+Spring+Hibernate)是一种非常流行的轻量级Web应用开发框架组合。通过整合这三个框架,开发者可以构建出功能强大且易于维护的...

    ssh框架下的常见问题处理方式,免费下载

    在Java SSH框架下开发...对于压缩包中的各个子文件,例如`发送邮件.rar`,可能包含了具体的邮件发送示例代码,`路径类.rar`可能涵盖了一些路径处理的实用方法,开发者可以通过解压学习这些例子来加深对知识点的理解。

    springMVC解决中文乱码

    解决 SpringMVC 中的中文乱码问题可以通过多种方法来实现,包括在 web.xml 文件中配置字符编码、使用注解配置字符编码、使用 CharacterEncodingFilter 或者自定义 Filter 等。这些方法都可以有效地解决中文乱码问题...

    SpringMVC Tomcat控制台乱码问题解决方案

    本文主要介绍了SpringMVC Tomcat控制台乱码问题解决方案,该解决方案通过示例代码进行了详细的介绍,对大家的学习或者工作具有一定的参考学习价值。下面将对该解决方案进行详细的解释。 一、乱码问题的来源 在使用...

Global site tag (gtag.js) - Google Analytics