`

spring编码过滤器(转:http://luckykapok918.blog.163.com/blog/static/2058650432012325540)

阅读更多

 很简单很实用的一个过滤器,当前台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常量来实现统一字符编码。

分享到:
评论

相关推荐

    http://www.robinhowlett.com/blog/2013/02/13/spring-app-migration-from-xml-to-jav

    NULL 博文链接:https://laravel.iteye.com/blog/2175915

    dubbo.xsd文件

    targetNamespace="http://code.alibabatech.com/schema/dubbo"&gt; &lt;xsd:import namespace="http://www.w3.org/XML/1998/namespace"/&gt; &lt;xsd:import namespace="http://www.springframework.org/schema/beans"/&gt; ...

    spring_MVC源码

    弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...

    http://www.blogjava.net/youlq/archive/2005/12/06/22678.html

    标题中的链接指向了一篇关于Acegi安全框架在Spring框架中使用的文章,而描述中的博文链接则是另一篇关于技术讨论的文章。结合标签“源码”和“工具”,我们可以推测这篇文章主要探讨的是如何通过Acegi安全框架来增强...

    成绩管理系统

    使用技术:spring MVC+hibernate+spring+easyui Jdk(最好使用jdk7):http://pan.baidu.com/s/1gd8APVl Tomcat(最好使用tomcat7): http://pan.baidu.com/s/1gd8APVl Mysql数据库:...

    mini_springboot:springboot极简教程:http://www.jianshu.comcc3fe8e7aeb09

    您可以通过运行以下命令启动应用程序:$ ./gradlew bootRun该项目使用kotlin-spring插件来避免在代理类和方法上需要open修饰符,有关更多详细信息,请参见此。 确保您至少具有IntelliJ IDEA 2016.3和Kotlin插件...

    Spring Framework 4.x Reference Documentation 中文翻译

    Spring Framework 4.x Reference Documentation 中文翻译 Chinese translation of the Spring Framework 4.x Reference Documentation ...

    css样式无法加载Refused to apply style from ‘http://localhost:8080/static/css/style.css’ because its MIME

    在这个具体的案例中,开发者在使用Spring Boot 2.0构建的Web应用中遇到了这个错误,错误信息显示,浏览器拒绝应用来自`http://localhost:8080/static/css/style.css`的样式,因为其MIME类型('application/json')...

    springsecurity_logout.rar

    SpringSecurity是Java领域中一个强大的安全框架,用于处理Web应用的安全性问题,如认证、授权等。在SpringSecurity中,登出(logout)功能是应用中不可或缺的一部分,它允许用户安全地结束当前会话,清除相关认证...

    从零开始学Spring Boot

    从零开始学Spring Boot,没有积分的可以看博客:http://412887952-qq-com.iteye.com/ 【Spring Boot 系列博客】 0)前言【从零开始学Spring Boot】 : http://412887952-qq-com.iteye.com/blog/2291496 (1...

    struts hibernate spring 集成时使用依赖注解的方式的秘籍

    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans ...

    基于协同过滤算法的商品推荐系统的设计与实现 springboot

    浏览器:谷歌浏览器 Java配置环境链接:https://pan.baidu.com/s/1Dzpiqb46mrukQzXOEj3otw 后台路径地址:localhost:8080/项目名称/admin/dist/index.html 前台路径地址:localhost:8080/项目名称/front/index....

    spring-ibatis

    spring-ibatis 整合 springmvc 配置: &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc=...

    仿https://start.spring.io的配置服务器

    解决创建IDEA创建SpringBoot时出现403的问题,使用方法见博客: https://blog.csdn.net/u013816347/article/details/80179239

    java springboot整合activemq工程

    spring.activemq.broker-url=failover:(tcp://10.0.1.227:61616,tcp://10.0.1.228:61616,tcp://10.0.1.229:61616,mqtt://10.0.1.227:1883,mqtt://10.0.1.228:1883,mqtt://10.0.1.229:1883) #spring.activemq.broker-...

    java常用资源下载地址

    4. **Spring**:Spring是一个全面的企业级应用框架,它提供了依赖注入、AOP(面向切面编程)等功能: - Spring官方站点:http://www.springframework.org/ - Spring中文论坛:http://spring.jactiongroup.net/ - ...

    Spring实战2-Bean注入详解的源代码

    xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context=...

    springmvc-config.xml

    这是一个springmvc-config.xml文件,&lt;?xml version="1.0" encoding="UTF-8"?&gt; xmlns:xsi=... http://www.springframework.org/schema/context/spring-context-4.2.xsd"&gt;

    SpringMVC+Spring+Spring Data JPA+Maven

    技术博客:http://zhc3191012.blog.163.com/ 技术架构:SpringMVC3+Spring3.1.2+Spring Data JPA+Maven 声明:该应用仅仅是技术研究:Spring Data JPA的配置和常见api的使用&maven构建项目,其他技术不在此研究 ...

    解决IntelliJ IDEA创建spring boot无法连接http://start.spring.io/问题

    主要介绍了解决IntelliJ IDEA创建spring boot无法连接http://start.spring.io/问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics