SpringMVC的@ResponseBody注解可以将请求方法返回的对象直接转换成JSON对象,但是当返回值是String的时候,中文会乱码
原因是因为其中字符串转换和对象转换用的是两个转换器,而String的转换器中固定了转换编码为"ISO-8859-1"
网上也很多种解决方法,有通过配置Bean编码的,也有自己重写转换器的,我这里多次尝试未果,只能自己解决。
有两种解决办法:
1.返回字符串时,将字符串结果转换
2.添加@RequestMapping注解,配置produces的值
由于我是为了使用JSONP协议,需要连同callback一起返回,所以我定义的是
- @RequestMapping(value = "/add", params = {"callback"}, produces = {"text/javascript;charset=UTF-8"})
以上提供的方法虽然需要额外配置,但相对灵活,喜欢一次性永久搞定的,还是应该考虑网上的方法,修改源码,或者替换默认的字符串转换器。
但是在使用<mvc:annotation-driven />配置的前提下,貌似网上的方法都不可靠,可能跟版本或者配置有关系
这边提供一种修改方法,我这边使用的是3.1的mvc
1.参考网上将默认的StringHttpMessageConverter重写一遍,将其中的编码改为UTF-8
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.UnsupportedEncodingException;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.List;
- 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.FileCopyUtils;
- public class UTF8StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
- public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
- private final List<Charset> availableCharsets;
- private boolean writeAcceptCharset = true;
- public UTF8StringHttpMessageConverter() {
- super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL);
- this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
- }
- /**
- * Indicates whether the {@code Accept-Charset} should be written to any outgoing request.
- * <p>Default is {@code true}.
- */
- public void setWriteAcceptCharset(boolean writeAcceptCharset) {
- this.writeAcceptCharset = writeAcceptCharset;
- }
- @Override
- public boolean supports(Class<?> clazz) {
- return String.class.equals(clazz);
- }
- @Override
- protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
- Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
- return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
- }
- @Override
- protected Long getContentLength(String s, MediaType contentType) {
- Charset charset = getContentTypeCharset(contentType);
- try {
- return (long) s.getBytes(charset.name()).length;
- }
- catch (UnsupportedEncodingException ex) {
- // should not occur
- throw new InternalError(ex.getMessage());
- }
- }
- @Override
- protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {
- if (writeAcceptCharset) {
- outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
- }
- Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
- FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));
- }
- /**
- * Return the list of supported {@link Charset}.
- *
- * <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
- *
- * @return the list of accepted charsets
- */
- protected List<Charset> getAcceptedCharsets() {
- return this.availableCharsets;
- }
- private Charset getContentTypeCharset(MediaType contentType) {
- if (contentType != null && contentType.getCharSet() != null) {
- return contentType.getCharSet();
- }
- else {
- return DEFAULT_CHARSET;
- }
- }
- }
2.context配置
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
- xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.1.xsd">
- <mvc:annotation-driven>
- <mvc:message-converters>
- <bean class="yourpackage.UTF8StringHttpMessageConverter" />
- </mvc:message-converters>
- </mvc:annotation-driven>
- ......
- </beans>