Spring框架:@ResponseBody 中文乱码----------我的主题站内单点登录
问题背景
本文并不是介绍@ResponseBody注解,也不是中文乱码问题的大汇总笔记,这些网上都有很多内容了。这边仅对几年前,一个卡壳了挺久时间的问题的解决过程做一个记录,以警惕自己,达到自醒得目的。
@ReponseBody 注解不用多介绍了,用过SpringMVC的同学都很熟了,@ResponseBody 将内容或对象作为 HTTP 响应正文返回,使用@ResponseBody将会跳过视图处理部分,而是调用适合的HttpMessageConverter,将返回值写入输出流。在日常工作中,通常使用封装好的ViewModel进行后台数据的返回,一切正常。但一次在使用@ReponseBody进行返回String数据的时候,竟会出现中文乱码。
编程的过程免不了遇到各种问题,而遇到问题然后解决问题的这个过程我认为是最让人兴奋的事情。越棘手的问题,解决以后带来的快感也越大(PS:当然解决不了的话,就会越烦躁。。),还是言归正传,谈一下解决错误的过程。
问题分析
最早我一直以为Spring配置一下编码过滤器就可以解决任何中文乱码问题,代码如下: 恩,确实一直是这样设置着,然并卵。

<filter><filter-name>characterEncodingFilter</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>true</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

直接返回String会乱码,而返回ViewModel的那个不会乱码,这是为什么?
其实也可以说是SpringMVC的一个bug,SpringMVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回VM则使用MappingJacksonHttpMessageConverter,若返回String,则使用StringHttpMessageConverter,这个convert使用的是字符集是iso-8859-1,而且是final的,如下:
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
既然是String有问题,那自然就直接从适配器AnnotationMethodHandlerAdapter 的字符串解析器 StringHttpMessageConverter 入手,设置编码类型即可?

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><bean class="org.springframework.http.converter.StringHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/plain;charset=UTF-8</value></list></property></bean>
...

NO!
那万金油response.setContentType("text/html; charset=UTF-8");呢?NO!
那么重写StringHttpMessageConverter应该可以了吗?NO!
上面方法都不行,就尝试着各种百度,说法多种多样,但答案还是:NO!
问题解决
恩,看来我们得从源头开始再理一遍,既然问题在解析器,那么可以从配置文件配置解析器的配置文件入手。mvc-config.xml 文件从上到下:控制层扫描、国际化配置、文件上传表单解析器、自定义拦截器、视图配置。好像都不是,继续往下,一些HandlerMapping和HandlerAdapter,还有一句<mvc:annotation-driven/>。
网上查阅了一下资料,果然发现问题其实就在这句<mvc:annotation-driven/>。
<mvc:annotation-driven /> 是一种简写模式,它会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的,并且提供了其他一些支持。。。略
上面使用为StringHttpMessageConverter设置编码模式其实正常是有效的,但是在使用了<mvc:annotation-driven />语句后,再次显示声明其他bean,可能就无效了。

<mvc:annotation-driven><mvc:message-converters><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="UTF-8"/></bean></mvc:message-converters></mvc:annotation-driven>

扩展:其他解决方案
除了使用上面那种方案之外,还可以使用下面的:
1、完全不使用String返回,直接都通过统一的ViewModel去返回,如ResultModel等(正常也是这么干的,总还要错误信息等吧);
2、通过@RequestMapping的属性处理,该注解的属性produces用于指定返回的内容类型,这算肯定可以了,代码如下:
@RequestMapping(value="/test", method=RequestMethod.POST, produces="text/html;charset=UTF-8")
注意:既然使用了配置<mvc:annotation-driven>,还是建议在该配置内部进行处理。
编后语
上面的问题记录是很多多年前的了,现在翻到博客上,只是为了告诫自己:
天下文章一大抄,但是抄来抄去,不管是写的人,还是看的人,自己最好都能理解或者亲自去尝试一下;这个乱码问题网上总结太多太多了,不能说是错误的,但是又有几个正确得说清楚呢?
如果放在现在来解决这个问题,最好的方案还是直接跟一下SpringMVC的源码,简单明了。String类型的返回值处理会进入StringHttpMessageConverter解析器,观察getContentTypeCharset方法的参数,可以看到当前解析编码是text/plain;charset=ISO-8859-1,即设置不成功,设置不成功可以继续看看适配器AnnotationMethodHandlerAdapter的属性设置,一层层反推,总会发现问题的。
这里奉劝各位兄弟姐妹,网上的东西还是要仔细研究的,不要转来转去的。
Spring框架:@ResponseBody 中文乱码----------我的主题站内单点登录的更多相关文章
- 解决Spring框架下中文乱码的问题
在使用了Spring框架下回发现很多表单交互的地方会发生乱码,而且写到数据库中也是乱码,这其实还是字符编码的问题,在我们还在用自己写的servlet的时候,直接在request和response加上字 ...
- Hession集成Spring + maven依赖通讯comm项目 + 解决@ResponseBody中文乱码
hessian结合spring的demo hessian的maven依赖: <!-- hessian --> <dependency> < ...
- 《经久不衰的Spring框架:@ResponseBody 中文乱码》
问题背景 本文并不是介绍@ResponseBody注解,也不是中文乱码问题的大汇总笔记,这些网上都有很多内容了.这边仅对几年前,一个卡壳了挺久时间的问题的解决过程做一个记录,以警惕自己,达到自醒得目的 ...
- 《经久不衰的Spring框架:@ResponseBody 中文乱码》(转)
转载自:http://www.cnblogs.com/shanrengo/p/6429291.html 问题背景 本文并不是介绍@ResponseBody注解,也不是中文乱码问题的大汇总笔记,这些网上 ...
- Spring Mvc中@ResponseBody中文乱码解决,以及修改返回的Content-Type
http://www.codeif.com/topic/784 spring 3 mvc 的 @ResponseBody返回数据用起来很方便,但是中文乱码,而且返回的Content-Type不带编码信 ...
- easyUI 接收Spring Mvc中@ResponseBody中文乱码解决
接触springMVC不够深入,乱码困扰我到深夜,特此留下记忆: @responsebody默认滴是ISO-8859-1 Controller注解参数 @ResponseBody 标注后返回Strin ...
- SpringMvc返回@ResponseBody中文乱码
使用SpringMvc的@ResponseBody返回指定数据的类型做为http体向外输出,在浏览器里返回的内容里有中文,会出现乱码,项目的编码.tomcat编码等都已设置成utf-8,如下返回的是一 ...
- Spring MVC POST中文乱码解决方案
spring Web MVC框架提供了org.springframework.web.filter.CharacterEncodingFilter用于解决POST方式造成的中文乱码问题,具体配置如下: ...
- 使用SpringMVC框架解决中文乱码的问题
spring Web MVC框架提供了org.springframework.web.filter.CharacterEncodingFilter用于解决POST方式造成的中文乱码 问题. 需要在we ...
随机推荐
- jq里验证插件的自定义方法Jquery.validator.addMethod()示例
最近写验证的时候感觉原生的验证谢了一遍又一遍,就想到了“不要重复造轮子,学会管理自己的工具库”这句名言,于是尝试用jq的validator. 用过又发现需要自定义方法去验证,于是去查官网,写了Jque ...
- VS2013 密钥– 所有版本
Visual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9Visual Studio Premium 2013 KEY(密钥): ...
- 触发form表单的两种提交方式,submit和button的用法
1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写:有两种方法,一种是用submit提交.一种是用button提交. 方法一: 在jsp的前端页面 ...
- Angular2+ 编译后部署到服务器上页面刷新404问题
原因:NG2+ 会默认不显示URL后面的文件名 解决方案:使用LocationStrategy方式,然后把URL后的# 替换成index.html# app.module.ts import {Has ...
- 跟随我在oracle学习php(12)
DOM 文档对象模型 body:(什么时候)找到标签 操作标签找到标签:(都会返回一个js对象)document.getElementById() 通过iddocument.getElementsBy ...
- 利用this属性实现点击按钮变色.选中效果
浏览器宿主的全局环境中,this指的是window对象. <script type="text/javascript"> console.log(this === wi ...
- selenium自动化实例: 多层框架中关于iframe的定位,以及select下拉框选择
对于一个自动化的初学者来说会很常见的遇到元素明明存在却始终定位不到, 从而导致脚本报错,当然定位不到元素的原因很多, 其中一种就是多层框架iframe导致的 下方截图示意: 下方为写脚本时候的示例并其 ...
- Mysql 源码:关于innodb中两次写的探索
转载自:http://www.cnblogs.com/bamboos/p/3553703.html?utm_source=tuicool&utm_medium=referral 两次写可以说是 ...
- python 生成器(generator)的生成方式
generator包括生成器和带yield的generator函数. 写了一个生成杨辉三角的小例子: # -*- coding:utf-8 -*- def triangles(): l = [1] w ...
- javascript--返回顶部效果
window.onload = function(){ var obtn = document.getElementById('btn'); //客户端页面可视区高度 var clientHeight ...