org.springframework.web.filter.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});
说明:
1. 静态常量responseSetCharacterEncodingAvailable 是通过反射来判断response是否有setCharacterEncoding方法,返回值应该都是true.
2. this.encoding != null :当encoding初始化参数被指定时条件满足。
3. (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常量来实现统一字符编码。
org.springframework.web.filter.CharacterEncodingFilter的更多相关文章
- java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
今天在用git merge 新代码后报了如下错误:java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterE ...
- 通过org.springframework.web.filter.CharacterEncodingFilter定义Spring web请求的编码
通过类org.springframework.web.filter.CharacterEncodingFilter,定义request和response的编码.具体做法是,在web.xml中定义一个F ...
- java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter
java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast ...
- SpringMVC------报错:java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
详细信息: java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter 严重: E ...
- java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast
严重: Exception starting filter encodingFilterjava.lang.ClassCastException: org.springframework.web.fi ...
- 关于org.springframework.web.filter.CharacterEncodingFilter的学习
介绍 org.springframework.web.filter.CharacterEncodingFilter 这是一个过滤器,是Spring在web请求中定义request和response的编 ...
- Eclipse中maven项目报错:org.springframework.web.filter.CharacterEncodingFilter
写了一个demo,发现在tomcat中部署完项目,启动时报错. 1,问题描述 2,解决办法 1)程序在部署完成后报错,说明是程序是编译通过的,即编译编译路径Java Build Path没问题.2)此 ...
- Maven项目启动报错:org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter
看网上说法tomcat启动时会把lib目录下的jar包加载进内存,而项目里也有相同的jar包就会导致jar包冲突 解决办法: 把pom依赖里相应的jar包添加<scope>标签 <d ...
- 'org.springframework.web.filter.CharacterEncodingFilter' is not assignable to 'javax.servlet.Filter,This inspection lets you spot the following problems that might occur in descriptors that are used t
1.jar包导入错误,因为maven下载的原因: 删除这样的包,然后让maven重新下载,问题就会解决
随机推荐
- hive 中 union all
hive 中的union all是不能在sql语句的第一层使用的,否则会报 Top level UNION is not supported currently 错误: 例如如下的方式: select ...
- html网页标题
HTML代码 <html> <head> <!--<title>定义网页标题,显示在浏览器的标题--> <title>网页标题</ti ...
- Java 解惑:Random 种子的作用、含参与不含参构造函数区别
Random 通常用来作为随机数生成器,它有两个构造方法: Random random = new Random(); Random random2 = new Random(50); 1.不含参构造 ...
- ibatis 的 "This SQL map does not contain a MappedStatement"的错误
This SQL map does not contain a MappedStatement named List 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有 ...
- zendstudio添加注释快捷键
最常用的是ctrl+/来添加行注释 方法是选中代码,按ctrl+/就可以注释掉代码.再按ctrl+/可以去掉注释 添加块注释时,现加/,再加*,再按enter即可添加块注释.
- 让IE9支持html5
IE10以上才算是真正支持了html5 ,但仍然有些地方和别的浏览器不一致,比如要在js里移除一个html标签, 如果是IE,document.getElementById("a" ...
- python矩阵运算 不断收集整理
python矩阵运算 转自:http://blog.sina.com.cn/s/blog_5f234d4701012p64.html Python使用NumPy包完成了对N-维数组的快速便捷操作.使用 ...
- Linux主机硬盘的主要规划
系统对于硬盘的需求跟刚刚提到的主机开放的服务有关,那么除了这点之外,还有没有其他的注意事项?当然有,那就是数据的分类与数据安全性的考虑,即当主机系统的硬件出现问题时,你的档案数据能否安全的保存. 前篇 ...
- Redis的初步安装
Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 下载 官网下载:http://redis.io/downlo ...
- Linux启动流程详解
在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多:一般就是通电.BIOS.主引导记录.操作系统这四步.所以我们一般认为加载内核是linux启动流程的第一步. 第一步.加载内核 操作系统接 ...