SpringMVC中 解决@ResponseBody注解返回中文乱码
问题:
在前端通过get请求服务端返回String类型的服务时,会出现中文乱码问题
原因:
由于spring默认对String类型的返回的编码采用的是 StringHttpMessageConverter
>>> spring mvc的一个bug,spring MVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list则使用MappingJacksonHttpMessageConverter,返回string,则使用StringHttpMessageConverter,这个convert使用的是字符集是iso-8859-1,而且是final的:
public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
解决办法:
方案一:
对于需要返回字符串的方法添加注解,如下:只针对单个方法生效,不全局生效
@RequestMapping(value = "/getUsers", produces = "application/json; charset=utf-8")
public String getAllUser()throws JsonGenerationException, JsonMappingException, IOException{
List < User > users = userService.getAll();
ObjectMapper om = new ObjectMapper();
System.out.println(om.writeValueAsString(users));
DataGrid dg = new DataGrid();
dg.setData(users);
return om.writeValueAsString(dg);
}
方案二:
在spring-servlet.xml中加入:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
方案三:
重写一个MessageConverter,然后注册到AnnotationMethodHandlerAdapter
package com.h5.common.converter; import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.util.StreamUtils; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List; public class EncodingAdapter extends AbstractHttpMessageConverter < String > {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private final Charset defaultCharset;
private final List < Charset > availableCharsets;
private boolean writeAcceptCharset; public EncodingAdapter() {
this(DEFAULT_CHARSET);
} public EncodingAdapter(Charset defaultCharset) {
super(new MediaType[]{
new MediaType("text", "plain", defaultCharset),
MediaType.ALL
});
this.writeAcceptCharset = true;
this.defaultCharset = defaultCharset;
this.availableCharsets = new ArrayList(Charset.availableCharsets().values());
} public void setWriteAcceptCharset(boolean writeAcceptCharset) {
this.writeAcceptCharset = writeAcceptCharset;
} public boolean supports(Class < ? > clazz) {
return String.class == clazz;
} protected String readInternal(Class < ? extends String > clazz, HttpInputMessage inputMessage)throws IOException {
Charset charset = this.getContentTypeCharset(inputMessage.getHeaders().getContentType());
return StreamUtils.copyToString(inputMessage.getBody(), charset);
} protected Long getContentLength(String str, MediaType contentType) {
Charset charset = this.getContentTypeCharset(contentType); try {
return Long.valueOf((long)str.getBytes(charset.name()).length);
} catch (UnsupportedEncodingException var5) {
throw new IllegalStateException(var5);
}
} protected void writeInternal(String str, HttpOutputMessage outputMessage)throws IOException {
if (this.writeAcceptCharset) {
outputMessage.getHeaders().setAcceptCharset(this.getAcceptedCharsets());
} Charset charset = this.getContentTypeCharset(outputMessage.getHeaders().getContentType());
StreamUtils.copy(str, charset, outputMessage.getBody());
} protected List < Charset > getAcceptedCharsets() {
return this.availableCharsets;
} private Charset getContentTypeCharset(MediaType contentType) {
return contentType != null && contentType.getCharSet() != null ? contentType.getCharSet() : this.defaultCharset;
}
}
//注册方法一:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean class="com.ctrip.hotel.h5.common.converter.EncodingAdapter ">
<constructor-arg index="0" value="UTF-8"/>
</bean>
</util:list>
</property>
</bean>
//注册方法二:
在webconfig.java中:
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
EncodingAdapter stringConverter = new EncodingAdapter();
converters.add(0, stringConverter);
}
方案四:
直接新建一个如下的类,放入代码即可。
package com.h5.common.encode; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor; import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List; /**
* Created by xingyuzhu on 2017/2/27.
* 解决@ResponseBody返回的响应中中文乱码问题.
*/
@Component
public class EncodingPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException{
if (bean instanceof RequestMappingHandlerAdapter) {
List < HttpMessageConverter < ? >> convs = ((RequestMappingHandlerAdapter)bean).getMessageConverters();
for (HttpMessageConverter < ? > conv : convs) {
if (conv instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter)conv).setSupportedMediaTypes(
Arrays.asList(new MediaType("text", "html",
Charset.forName("UTF-8"))));
}
}
}
if (bean instanceof RequestResponseBodyMethodProcessor) {
List < HttpMessageConverter < ? >> convs = ((RequestMappingHandlerAdapter)bean).getMessageConverters();
for (HttpMessageConverter < ? > conv : convs) {
if (conv instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter)conv).setSupportedMediaTypes(
Arrays.asList(new MediaType("text", "html",
Charset.forName("UTF-8"))));
}
}
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException{
return bean;
}
}
方案五:
在我们的webconfig.java中,注册一个bean:该方法有缺陷RequestMappingHandlerAdapter中的其他messageconverter丢失,导致其他问题,比如返回的是一个jsp页面,就会挂掉
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter reqMapHAdapter = new RequestMappingHandlerAdapter();
ArrayList < HttpMessageConverter < ? >> msgConvs = new ArrayList < > ();
StringHttpMessageConverter stringConverter = new
StringHttpMessageConverter(Charset.forName("UTF-8"));
stringConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN));
msgConvs.add(stringConverter);
reqMapHAdapter.setMessageConverters(msgConvs);
return reqMapHAdapter;
}
方案六:
在webconfig.java中:
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
converters.add(0, stringConverter);
}
方案七:(篡改框架的编码,推荐使用)
在webconfig.java中,篡改一下StringHttpMessageConverter的编码方式
@Override
public void extendMessageConverters(List < HttpMessageConverter < ? >> converters) {
HttpMessageConverter converter = Iterables.find(converters, new Predicate < HttpMessageConverter < ? >> () {
@ Override
public boolean apply( @ Nullable HttpMessageConverter < ? > input) {
return input != null && input instanceof StringHttpMessageConverter;
}
}, null);
if (converter == null) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "html", Charset.forName(UTF8))));
converters.add(1, stringConverter); //默认的StringHttpMessageConverter在第二个位置
return;
}
StringHttpMessageConverter stringHttpMessageConverter = (StringHttpMessageConverter)converter;
stringHttpMessageConverter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "html", Charset.forName(UTF8))));
}
SpringMVC中 解决@ResponseBody注解返回中文乱码的更多相关文章
- springmvc 解决@ResponseBody注解返回中文乱码
使用messageConverters <bean class="org.springframework.web.servlet.mvc.method.annotation.Reque ...
- 记一次@ResponseBody注解返回中文乱码的问题
Bug场景 前端AJax $.ajax({ url: '$!{request.getContextPath()}/XX/save.do', type: 'post', dataType: 'json' ...
- @ResponseBody注解返回中文乱码
第一种方法: @RequestMapping(value = "testPersonalValidtor",produces = "application/json;ch ...
- 解决@ResponseBody注解返回的json中文乱码问题
1. 简介 主要解决@ResponseBody注解返回的json中文乱码问题. 2.解决方案 2.1mvc加上注解(推荐此方法) 在mvc配置文件中假如下面配置(写在 <mvc:annotati ...
- SpringMVC使用@ResponseBody注解返回中文字符串乱码的问题
先说一下我的经历,以及解决问题的而过程. 在使用SpringMVC的时候,最开始的时候在配置文件中使用<mvc:annotation-driven />去自动注册DefaultAnnota ...
- spring mvc 返回乱码SpringMVC使用@ResponseBody注解返回中文字符串乱码的问题
原文地址:https://www.cnblogs.com/fzj16888/p/5923232.html 先说一下我的经历,以及解决问题的而过程. 在使用SpringMVC的时候,最开始的时候在配置文 ...
- 解决spring-mvc @responseBody注解返回json 乱码问题
在使用spring-mvc的mvc的时候既享受它带来的便捷,又头痛它的一些问题,比如经典的中文乱码问题.现在是用json作为客户端和服务端 的数据交换格式貌似很流行,但是在springmvc中有时候会 ...
- spring 3.0 @ResponseBody注解返回中文问号乱码解决办法
前几天给公司做项目,很久没接触java项目的我,遇到了一个问题,就是我在利用异步到控制器中查询,然后返回jaon字符串到前台,字符串中包含中文,于是我直接用了@ResponseBody注解,来返回到前 ...
- SpringMVC中使用@ResponseBody注解将任意POJO对象返回值转换成json进行返回
@ResponseBody 作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区. ...
随机推荐
- Python 字符串语法,for
#-*- coding:utf-8 -*- #字符串的拼接方式一 a = "hello" b = "world" c = a + " " + ...
- 自然语言交流系统 phxnet团队 创新实训 项目博客 (一)
2D文字聊天界面大致预期实现文字输入.发送消息.接收消息.你可以通过点击按钮让机器人开启聊天模式或者学习模式.又或是进入3D语音聊天界面或者退出. 目背景 (1) 开发动机的形态 随着科技的进步与生活 ...
- Spring 4 官方文档学习(十一)Web MVC 框架之Flash Attributes
接上一篇中的重定向. http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-fl ...
- 有了malloc/free 为什么还要new/delete ?
有了malloc/free 为什么还要new/delete ? malloc 与 free 是 C++/C 语言的标准库函数,new/delete 是 C++的运算符.它们都可 用于申请动态内存和释放 ...
- ffmpeg h264+ts +udp传输
http://bbs.csdn.net/topics/370246456 http://1229363.blog.163.com/blog/static/19743427201001244711137 ...
- Android camera 竖直拍照 获取竖直方向照片
竖直拍照 if (Integer.parseInt(Build.VERSION.SDK) >= 8) { camera.setDisplayOrientation(90); } else ...
- 关于HTTP keep-alive的实验(转至 http://my.oschina.net/flashsword/blog/80037)
前面一篇文章提到,HTTP1.1中持久连接已经是默认配置,除非设置Connection为close,否则默认都会进行持久连接.但是我们知道事实标准跟教科书还是可能会有一定差距的,所以不妨自己尝试一下. ...
- php中常用$_SERVER的用法
#测试网址: http://localhost/blog/testurl.php?id=5 //获取域名或主机地址 echo $_SERVER['HTTP_HOST']."<br> ...
- 学习 TList 类的实现[7]
总结目前 TMyList 已具备的功能(3 个方法.3 个属性): Add: 添加; Delete: 删除; Clear: 清空;Count: 元素总数;Capacity: 已存在的所有元素位置数;L ...
- 深入理解bootstrap框架之第二章整体架构
标注下,正好最近关注前段框架 1. CSS-12栅格系统 把网页宽度均分为12等分(保留15位精度)——这是bootstrap的核心功能. 2.基础布局组件 包括排版.按钮.表格.布局.表单等等. 3 ...