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

转载于:https://blog.51cto.com/xuliangjun/1365659

CharacterEncodingFilter作用相关推荐

  1. Spring MVC+Spring +Hibernate配置事务,但是事务不起作用

    最近做项目,被一个问题烦恼了很久.使用Spring MVC+Spring +Hibernate开发项目,在使用注解配置事务管理,刚开始发现无论如何数据库都无法更新,但是可以从数据库查询到数据.怀疑是配 ...

  2. SpringMVC是什么?有什么作用,能干什么

    SpringMVC 1.SpringMVC简介 1.1.什么是SpringMVC? 1.2.SpringMVC的特点 2.SpringMVC使用的准备 3.@RequestMapping注解 3.3. ...

  3. SSM框架工作原理、作用及使用方法

    作用: SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层 使用spring ...

  4. Object的finalize()方法的作用是否与C++的析构函数作用相同

    Object的finalize()方法的作用是否与C++的析构函数作用相同 public class Finalization {private static Finalization finaliz ...

  5. 浅显易懂 Makefile 入门 (02)— 普通变量和自动变量定义、使用($@、$^、$< 作用)、变量覆盖 override、变量的来源 origin

    1. 变量的定义 Makefile 文件中定义变量的基本语法如下: 变量的名称=值列表 变量的名称可以由大小写字母.阿拉伯数字和下划线构成.等号左右的空白符没有明确的要求,因为在执行 make 的时候 ...

  6. 【B/S实践】解决:vs中修改样式表后不起作用的问题

    缓存,有好多,cpu和内存之间的三级缓存,浏览器内的缓存! 缓存是因为速率不对等,通过缓存来加速内容的显示! 今天我在敲牛腩的时候遇到一个问题,找了半小时,才发现是缓存导致的问题! 试着运行aspx文 ...

  7. 卷积神经网络之卷积计算、作用与思想 深度学习

    博客:blog.shinelee.me | 博客园 | CSDN 卷积运算与相关运算 在计算机视觉领域,卷积核.滤波器通常为较小尺寸的矩阵,比如3×33×3.从这个角度看,多层卷积是在进行逐层映射,整 ...

  8. 机器学习——标准化/归一化的目的、作用和场景

    对每个特征进行归一化处理,使得每个特征的取值缩放到0~1之间.这样做有两个好处: 模型训练更高效. 特征前的权重大小可代表该变量对预测结果的贡献度(因为每个特征值本身的范围相同). (一)归一化的作用 ...

  9. Linux操作系统下文件作用

    linux下的文件结构,看看每个文件夹都是干吗用的 /bin 二进制可执行命令 /dev 设备特殊文件 /etc 系统管理和配置文件 /etc/rc.d 启动的配置文件和脚本 /home 用户主目录的 ...

最新文章

  1. 如何判断Java中两个Class对象是否相同
  2. android 弹出编辑框,Android编程实现的EditText弹出打开和关闭工具类
  3. java七大_Java 7七大新功能
  4. java基础知识大全,java 基础知识点汇总
  5. 系统页面升级系统中_国产系统哪家强?华为EMUI系统大升级,拿下最强指日可待...
  6. Angular开发准备
  7. IT众包Web网站服务案例:江苏保税店
  8. 非NLB网段的客户端无法访问NLB
  9. linux安装mysql5.7.24_下载安装 Ubuntu 19.04 “Disco Dingo” | Linux 中国
  10. php cimage类,强大的多功能的用VB编写的高速图像处理库Cimage简介! - 小志的日志 - 电子工程世界-论坛...
  11. java-多线程编程
  12. 《电路》邱关源 思维导图 第二章 电阻电路的等效变换
  13. 软件民工的幸福生活3
  14. EtherCAT主站SOEM函数详解---- ecx_readstate、ecx_writestate
  15. 人工智能 | ShowMeAI资讯日报 #2022.06.25
  16. gorm 记录sql日志 每天一个日志文件
  17. 手办 android app,hpoi手办维基
  18. Go-Micro微服务框架使用
  19. 整理的最新WebSHell (php过狗一句话,过狗菜刀,2016过狗一句话,2016php免杀一句话)
  20. linux里用于剪切文件,Linux_拷贝,剪切,删除和创建文件

热门文章

  1. mysql分窗函数_频谱分析中如何选择合适的窗函数
  2. thinkphp开发的活动报名小程序源码带后台管理完整的报名小程序源码
  3. DTS-SHOP微信小程序多店铺商城平台java源码
  4. 陌生人交友IM即时聊天系统-得推交友系统v3.0源码
  5. 云之道律师小程序源码V1.2.8完整全开源 安装包+小程序前端
  6. 全网最新Spring Boot2.5.1整合Activiti5.22.0企业实战教程<流程挂起与激活篇>
  7. 创建代码生成器可以很简单:如何通过T4模板生成代码?[上篇]
  8. 【新手教程】CE找武林外传基址方法
  9. php合成或者创建gif动画
  10. 15个友好的jQuery 提示框插件