问题:
在前端通过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))));
}

Spring MVC @ResponseBody响应中文乱码的更多相关文章

  1. Spring下@ResponseBody响应中文内容乱码问题

    引言: 在JQuery的Ajax请求中,收到的基于后台返回回来的结果出现乱码,在后台其内容正确,到了前台之后,确是乱码??????,该怎样解决呢? 1.  问题的提出 前端基于JQuery的Ajax进 ...

  2. 解决Spring MVC @ResponseBody返回中文字符串乱码问题

    spring mvc使用的默认处理字符串编码为ISO-8859-1 解决方法: 第一种方法: 对于需要返回字符串的方法添加注解,如下: @RequestMapping(value="/use ...

  3. spring mvc get请求中文乱码问题

    使用Spring MVC进行get请求时发现get请求带上中文参数,后台收到的是乱码,即使加了encoding filter也没用. 原因是,encoding filter 是针对post请求的,to ...

  4. Spring MVC @ResponseBody返回中文字符串乱码问题

    朋友做小项目练手的时候遇到的,着实让他郁闷够呛..这个问题的确很恶心.. 项目中引用的json包,直接用@ResponseBody注解返回json字符串..有关这个的乱码问题网上很多,各种花样各种转码 ...

  5. 解决Spring MVC @ResponseBody出现问号乱码问题

    原因是SpringMVC的@ResponseBody使用的默认处理字符串编码为ISO-8859-1,而我们前台或者客户端的编码一般是UTF-8或者GBK.现将解决方法分享如下! 第一种方法: 对于需要 ...

  6. spring mvc后台接收中文乱码

    可从如下几方面着手 1.jsp页面编码 2.web.xml配置字符过滤器,该字符过滤器最好放在开头 3.tomcat下server.xml添加URIEncoding="UTF-8" ...

  7. spring mvc请求参数中文乱码解决方案

    POST 请求 在web.xml中加上增加过滤器 <filter> <filter-name>encodingFilter</filter-name> <fi ...

  8. 1、spring mvc jsp页面中文乱码

    jsp 页面头部 的page标签中加个 contentType="text/html;charset=utf-8"

  9. Springboot @ResponseBody返回中文乱码

    最近我在把Spring 项目改造Springboot,遇到一个问题@ResponseBody返回中文乱码,因为response返回的content-type一直是application/json;ch ...

随机推荐

  1. 小程序之Button组件,函数的调用与简单的逻辑

    我们要实现一个简单的功能,在界面上放置一张图片,设置重新加载按钮,能更新图片. WXML代码: <!--index.wxml--> <view clas="index&qu ...

  2. nginx+tomcat实现简单的负载均衡

    host1:10.0.0.10(部署nginx和tomcat) host2:10.0.0.11(部署tomcat) 平台环境(2主机一样) [root@smp ~]# uname -r3.10.0-8 ...

  3. tiny4412学习笔记-将uboot、zImage、文件系统烧到emmc中 (转)

    http://blog.chinaunix.net/uid-30025978-id-4788683.html 1.首先还是要将u-boot写入SD卡中从SD卡启动. 使用读卡器将SD插入电脑中,使用u ...

  4. Turtle库学习

    Python Turtle (Python绘图工具) 导入库 import turtle as t ps:为了方便调用我们这里给这个模块在本程序内重命名为 t 1. 画布 顾名思义就是用于绘图的区域 ...

  5. 小白安装Python环境详细步骤!

    昨天,有小伙伴向我反映,他对我说“你好像还没教过我安装Python的吧?”听到这句话,我不禁汗颜起来,我的确好像没太注意Python学习的基础了,一直发各种爬虫与初学者看不懂的代码,在此我要向我的读者 ...

  6. Linux 基本操作指南

    Linux基本操作 1. su  切换用户   2.exit 退出当前登录用户 3.useradd 用户名  -m  在home目录下 创建一个和用户名同名的目录,并添加一个用户 (有root权限才能 ...

  7. python re 正则表达式

    元字符和其含义 . 匹配除换行符以外的任意字符 \ 转义字符,使后一个字符改变原来的意思 \w 匹配字母.数字.下划线:[A-Za-z0-9_] \W 匹配特殊字符:[^A-Za-z0-9_] \s ...

  8. 【HIHOCODER 1052 】基因工程(贪心)

    链接 问题描述 小Hi和小Ho正在进行一项基因工程实验.他们要修改一段长度为N的DNA序列,使得这段DNA上最前面的K个碱基组成的序列与最后面的K个碱基组成的序列完全一致. 例如对于序列"A ...

  9. UI进阶 XML解析适配 'libxml/tree.h'file not found 错误解决办法

    Xcode 'libxml/tree.h'file not found 错误解决办法

  10. python+RobotFramework

    今天有人问我,她想在在robot里面用到数据库的一个值的随机数,但是不知道怎么实现,我用python写了一段代码链接数据库给表中所需的字段的值取随机数,代码如下: import random,pymy ...