[Spring MVC] @ResponseBody返回结果乱码问题的解决

发现问题

在Controller类方法上加@ResponseBody,直接返回字符串,结果乱码。

如下所示:

MockHttpServletResponse:

Status = 200

Error message = null

Headers = {Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[45]}

Content type = text/plain;charset=ISO-8859-1

Body = {

"Msg":"???????????????nameEntTypeCode??"

}

用浏览器访问也是乱码。

分析问题

1、分析日志

日志级别设为DEBUG,查看日志,节选如下:

(1)

<Method [handleRuleException] returned [{

"Msg":"调用时规则时未传入必要参数:“nameEntTypeCode”。"

}]>

到这里还是对的。Handle调用完成,获得了返回值,接下来归View了。

(2)

[email protected]]
supports [class java.lang.String]>

[email protected]]
supports [class java.lang.String]>

[email protected]6a5b]
supports [class java.lang.String]>

[email protected]a0]
supports [class java.lang.String]>

[email protected]]
supports [class java.lang.String]>

web.s[email protected]1c45fa4]
supports [class java.lang.String]>

快找到元凶了。

accept.PathExtensionContentNegotiationStrategy$JafMediaTypeFactory]

Loading Java Activation Framework FileTypeMap from class path resource

[org/springframework/mail/javamail/mime.types]    //默认支持的类型是从这里读取的

mvc.method.annotation.AbstractMessageConverterMethodProcessor<Written [{

"Msg":"调用时规则时未传入必要参数:“nameEntTypeCode”。"

}] as "text/plain;charset=ISO-8859-1" using [[email protected]fa83c]>

找到元凶。他是怎样作案的呢?

我猜,大概是StringHttpMessageConverter注入了AbstractMessageConverterMethodProcessor。

“text/plain;charset=ISO-8859-1”是StringHttpMessageConverter的属性。

2、尝试解决

(1)AbstractMessageConverterMethodProcessor是抽象类,在StringHttpMessageConverter上想办法。

(2)

如果org.springframework.http.converter.StringHttpMessageConverter是单例,可以自己配置一下看看

<bean id="stringHttpMessageConverter"

class="org.springframework.http.converter.StringHttpMessageConverter">

<property name="supportedMediaTypes">

<list>

<value>text/plain;charset=UTF-8</value>

</list>

</property>

</bean>

在<xxx>-servlet.xml中配置无效。确认放在<mvc:annotation-driven>之前了。

(3)注入的姿势不对,还是老实看看Spring源代码吧

3、寻找注入口

(1)

RequestMappingHandlerAdapter构造函数中:

public RequestMappingHandlerAdapter() {

StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();

...

this.messageConverters.add(stringHttpMessageConverter);

}

直接这么new啊,太粗暴了。

这只是默认行为,应该有覆盖办法的。

(2)

跟代码,跟到

private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {

List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();

// Single-purpose return value types

handlers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager));

// Annotation-based return value types

handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager));

}

然后找到:

public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {

this.messageConverters = messageConverters;

}

(3)

试试看:

<mvc:annotation-driven>

<mvc:message-converters>

<bean class="org.springframework.http.converter.StringHttpMessageConverter">

<property name="supportedMediaTypes">

<list>

<value>text/plain;charset=UTF-8</value>

</list>

</property>

</bean>

</mvc:message-converters>

</mvc:annotation-driven>

这就是老版本的报错吧:

cvc-complex-type.2.1: 元素 ‘mvc:annotation-driven‘ 必须不含字符或元素信息项 [子级], 因为该类型的内容类型为空。

看mvc命名空间中xsd版本。

好吧,就是这里:http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

(4)

修正,好了:

MockHttpServletResponse:

Status = 200

Error message = null

Headers = {Content-Type=[text/plain;charset=UTF-8], Content-Length=[79]}

Content type = text/plain;charset=UTF-8

Body = {

"Msg":"调用时规则时未传入必要参数:“nameEntTypeCode”。"

}

Forwarded URL = null

Redirected URL = null

Cookies = []

总结

1、遇到问题多看日志,多看代码。

2、Spring MVC注入口很多,太爽了,但应该谨慎使用,考虑影响范围。

3、HttpMessageConverter是神器,可以完成传入参数和返回值的转换,通过自定义Media Type可实现神奇效果,有机会好好研究下。

时间: 2024-10-05 17:43:41

[Spring MVC] @ResponseBody返回结果乱码问题的解决的相关文章

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

最近有个应用,通过responsebody返回完整的html页面时出现乱码是异常的问题,因为是通过responsebody返回,所以一开始设置了text/plain的字符集,如下: <mvc:annotation-driven>     <mvc:message-converters register-defaults="true">    <bean class="org.springframework.http.converter.Strin

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

引起乱码原因为spring mvc使用的默认处理字符串编码为ISO-8859-1,具体参考org.springframework.http.converter.StringHttpMessageConverter类中public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1"); 解决方法: 第一种方法: 对于需要返回字符串的方法添加注解,如下: @RequestMapping(value=&quo

Spring MVC @ResponseBody响应中文乱码

问题:在前端通过get请求服务端返回String类型的服务时,会出现中文乱码问题 原因:由于spring默认对String类型的返回的编码采用的是 StringHttpMessageConverter>>> spring mvc的一个bug,spring MVC有一系列HttpMessageConverter去处理用@ResponseBody注解的返回值,如返回list则使用MappingJacksonHttpMessageConverter,返回string,则使用StringHttp

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

朋友做小项目练手的时候遇到的,着实让他郁闷够呛..这个问题的确很恶心.. 项目中引用的json包,直接用@ResponseBody注解返回json字符串..有关这个的乱码问题网上很多,各种花样各种转码器方法,但是试了一遍基本都无效,很多已经过时了..这里说一下spring引的是3.2.8的jar包.这个也没什么好分析的,基本就是在尝试各种解决方案的有效性..最终有2种有效在spring3.0以上版本下.. @RequestMapping(value="/test", produces

spring mvc ajax返回值乱码

加入如下配置: <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.ByteArrayHtt

判断JSON是否为空 (用spring mvc @ResponseBody 自动返回的json串 )

判断JSON是否为空 (用spring mvc @ResponseBody 自动返回的json串 ) 知识分类:EXTJS  spring mvc json 记录时间: 20150708 简单描述:用json.length 属性长度来判断是否为空,在此过程中spring mvc 自动返回的json串是 字符串的类型,所以用.length的方式返回的则是字符串的长度(一般空的JSON 在此处返回的长度应为3),并不是数组的长度,在EXTJS中用Ext.decode(json); 则可以将字符串js

解决Spring MVC ResponseBody 乱码问题

解决Spring MVC ResponseBody 乱码问题 @RequestMapping(value="qxyjqyresult",produces = "plain/text; charset=UTF-8") @ResponseBody public String getQxyjqyResult(String filename) throws Throwable { return "中文" }

解决SpringMVC的@ResponseBody返回中文乱码

SpringMVC的@ResponseBody返回中文乱码的原因是SpringMVC默认处理的字符集是ISO-8859-1,在Spring的org.springframework.http.converter.StringHttpMessageConverter类中可以看到如下代码: public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1"); 解决返回中文乱码的问题有两种,第一种是局部的,只针

spring mvc @ResponseBody http报错406

项目使用的是spring mvc 3.2.4 ,在使用到@ResponseBody 的时候出现http 406的错误,解决方法: 在pom.xml中添加上一下代码就ok了. <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.3</version> <