蓝易云 - SpringMVC3的ResponseBody返回字符串乱码问题解决
摘要:SpringMVC3中@ResponseBody返回字符串出现中文乱码,主要原因是StringHttpMessageConverter默认使用ISO-8859-1编码。解决方案包括:1)单接口快速修复,在@RequestMapping添加produces="text/plain;charset=UTF-8";2)推荐全局配置StringHttpMessageConvert
SpringMVC3 里 @ResponseBody 返回字符串出现中文乱码,本质上是整条编码链路某个环节没有统一到 UTF-8,而默认落在了 ISO-8859-1 等单字节编码上。下面从原理到落地方案,一次讲清,适合直接在蓝易云项目中执行“编码治理专项”。🚀
一、问题本质:SpringMVC3 字符串返回为什么容易乱码?
在 SpringMVC3 中,@ResponseBody 返回 String 时,默认由 StringHttpMessageConverter 负责输出。关键点有两个:
-
这个转换器默认使用的编码经常是 ISO-8859-1;
-
容器(如 Tomcat)默认响应头里的
Content-Type也可能不带<span style="color:red;">charset=UTF-8</span>。
于是:
Controller 里明明返回的是 UTF-8 字符串,但浏览器按照 ISO-8859-1 去解码,中文立刻变“方块+问号”😅。
二、方案一:在 @RequestMapping 上显式指定 produces + charset(快速止血)
这是最直接、见效快的方式,适合单接口先验证问题。
@RequestMapping(
value = "/hello",
produces = "text/plain;charset=UTF-8"
)
@ResponseBody
public String hello() {
return "你好,蓝易云";
}
解释:
-
@RequestMapping:标记访问路径/hello的控制器方法。 -
produces = "text/plain;charset=UTF-8":-
text/plain表示响应类型是纯文本; -
charset=UTF-8强制响应头携带<span style="color:red;">UTF-8</span>编码信息,浏览器就会按照 UTF-8 解析。
-
-
@ResponseBody:告诉 SpringMVC,“不要走视图解析器,直接把返回值写到 HTTP 响应体”。
适合:
-
少量接口先验证,确认确实是编码问题;
-
单独返回文本(非 JSON)时精确控制类型。
不足:
-
每个接口都写一遍
produces,维护成本高; -
一旦接口多,容易遗漏。
三、方案二:全局配置 StringHttpMessageConverter 为 UTF-8(推荐工程实践)
从工程治理角度,更稳妥的路径是:统一把 SpringMVC 使用的 StringHttpMessageConverter 的默认编码改成 UTF-8,让所有 @ResponseBody 返回字符串“天然就是 UTF-8”。
1. SpringMVC3 XML 配置示例
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 全局字符串消息转换器,统一使用 UTF-8 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
解释:
-
<mvc:annotation-driven>:开启注解驱动的 SpringMVC(支持@RequestMapping、@ResponseBody等)。 -
<mvc:message-converters>:自定义消息转换器列表。 -
register-defaults="true":保留 Spring 默认的转换器,再额外追加自定义配置。 -
StringHttpMessageConverter:专门用于处理String类型返回值; -
supportedMediaTypes中统一指定<span style="color:red;">charset=UTF-8</span>:-
text/plain/text/html/application/json三类常用媒体类型都强制 UTF-8; -
此后你在 Controller 里写
@ResponseBody public String xxx(),默认就会用 UTF-8 输出,不再乱码。
-
这一套配好之后,大部分 @ResponseBody 字符串乱码问题可以“一键解决”,非常适合在蓝易云这类多模块项目中做为统一规范。✅
四、方案三:增加 CharacterEncodingFilter,统一请求/响应编码
除了 Spring 自身,还要确保整个 Web 应用请求/响应链路都在用 UTF-8。
在 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>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
解释:
-
CharacterEncodingFilter:Spring 提供的编码过滤器,用于在请求进入和响应返回时统一设置编码。 -
encoding=UTF-8:指定目标编码为 UTF-8。 -
forceEncoding=true:强制覆盖请求与响应的编码,而不是“看情况”跟随容器默认值。 -
url-pattern/*:对所有请求生效,避免个别接口“漏网”。
这个过滤器配合上文的 StringHttpMessageConverter UTF-8,可以从“入口 + 出口”双向锁死编码。
五、方案四:检查服务器与 JSP 层编码(收尾工作)
如果项目里还有 JSP 页或者使用模板引擎,需要进一步保证页面自身的声明也是 UTF-8,否则 Controller 解决了,页面还会“拖后腿”。
1. JSP 页头声明
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
解释:
-
contentType="text/html; charset=UTF-8":告诉浏览器响应内容是 HTML 且使用 UTF-8。 -
pageEncoding="UTF-8":指定 JSP 文件本身的保存编码,避免 JSP 被以 GBK/ANSI 打开后出现乱码。
2. Tomcat Connector 配置(可选但建议)
<Connector port="8080"
protocol="HTTP/1.1"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"
redirectPort="8443" />
解释:
-
URIEncoding="UTF-8":对 URL 中的参数(如中文路径)按 UTF-8 解码,避免路径/QueryString 乱码。 -
useBodyEncodingForURI="true":让请求体与 URI 使用同一编码策略,进一步减少差异。
这一步是“底座级”的保障,尤其是在有中文路径、查询参数的场景中,非常关键。🌐
六、SpringMVC3 @ResponseBody 字符串乱码成因与解决策略对比表(vditor/Markdown 可用)
| 维度 | 问题成因(常见坑) | 对应解决方案 | 是否推荐在蓝易云项目中统一执行 |
| ---------------------- | --------------------------------------------------------------- | -------------------------------------------------- | ------------------------------ |
| 控制器返回字符串编码 | 默认 `StringHttpMessageConverter` 使用 ISO-8859-1,导致中文乱码 | 全局配置 `<span style="color:red;">StringHttpMessageConverter UTF-8</span>` | ★★★★☆(强烈推荐) |
| 单接口临时修复 | 某些接口需要快速止血,浏览器解码错误 | 在 `@RequestMapping` 上增加 `produces="...;charset=UTF-8"` | ★★★☆☆(适合单接口验证/补丁) |
| 请求/响应整体编码链路 | 容器默认编码不统一,请求/响应中间被改成其它编码 | 添加 `<span style="color:red;">CharacterEncodingFilter</span>`,强制 UTF-8 | ★★★★★(必须有) |
| 页面/JSP 层 | JSP 保存为 GBK、页面未声明 UTF-8 | 页面头部设置 `contentType` 和 `pageEncoding` 为 UTF-8 | ★★★★☆ |
| 容器底层 URI 编码 | URL 含中文路径或参数,经由容器时被按错误编码解析 | 配置 Tomcat `URIEncoding="UTF-8"` 等参数 | ★★★★☆ |
七、落地建议:给蓝易云项目的一套“统一动作清单”
从实战角度,把上面内容压缩为一套可执行 checklist:
-
在 SpringMVC3 配置中,全局注册 StringHttpMessageConverter UTF-8;
-
在
web.xml中开启 CharacterEncodingFilter,并设置forceEncoding=true; -
检查 JSP / 模板文件的
<meta>/page声明,统一到 UTF-8; -
检查 Tomcat 等容器的
ConnectorURIEncoding/useBodyEncodingForURI; -
对个别还不放心的接口,在
@RequestMapping上临时增加produces="text/plain;charset=UTF-8"做验证; -
回归测试:
-
浏览器直接访问;
-
Postman / curl 调接口,看响应头
Content-Type是否带<span style="color:red;">charset=UTF-8</span>; -
日志中检查是否再出现“乱码块”。
-
做完这一轮,你在 SpringMVC3 中遇到的绝大多数 @ResponseBody 字符串乱码问题,基本可以一次性归零,后续新接口也能在统一规范下“开箱即用”。👍
更多推荐




所有评论(0)