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

来源:互联网 发布:安卓卡iphone在线软件 编辑:程序博客网 时间:2024/04/29 05:00

SpringMVC的@ResponseBody注解可以将请求方法返回的对象直接转换成JSON对象,但是当返回值是String的时候,中文会乱码

 

原因是因为其中字符串转换和对象转换用的是两个转换器,而String的转换器中固定了转换编码为"ISO-8859-1"

 

网上也很多种解决方法,有通过配置Bean编码的,也有自己重写转换器的,我这里多次尝试未果,只能自己解决。

 

有两种解决办法:

1.返回字符串时,将字符串结果转换

 

Java代码  收藏代码
  1. return new String("你好".getBytes(), "ISO-8859-1");  

 

2.添加@RequestMapping注解,配置produces的值

 

Java代码  收藏代码
  1. @RequestMapping(value = "/add", produces = {"application/json;charset=UTF-8"})  

 

由于我是为了使用JSONP协议,需要连同callback一起返回,所以我定义的是

 

Java代码  收藏代码
  1. @RequestMapping(value = "/add", params = {"callback"}, produces = {"text/javascript;charset=UTF-8"})  

 

以上提供的方法虽然需要额外配置,但相对灵活,喜欢一次性永久搞定的,还是应该考虑网上的方法,修改源码,或者替换默认的字符串转换器。

但是在使用<mvc:annotation-driven />配置的前提下,貌似网上的方法都不可靠,可能跟版本或者配置有关系

 

这边提供一种修改方法,我这边使用的是3.1的mvc

1.参考网上将默认的StringHttpMessageConverter重写一遍,将其中的编码改为UTF-8

Java代码  收藏代码
  1. import java.io.IOException;  
  2. import java.io.InputStreamReader;  
  3. import java.io.OutputStreamWriter;  
  4. import java.io.UnsupportedEncodingException;  
  5. import java.nio.charset.Charset;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. import org.springframework.http.HttpInputMessage;  
  10. import org.springframework.http.HttpOutputMessage;  
  11. import org.springframework.http.MediaType;  
  12. import org.springframework.http.converter.AbstractHttpMessageConverter;  
  13. import org.springframework.util.FileCopyUtils;  
  14.   
  15. public class UTF8StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {  
  16.   
  17.     public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");  
  18.   
  19.     private final List<Charset> availableCharsets;  
  20.   
  21.     private boolean writeAcceptCharset = true;  
  22.   
  23.     public UTF8StringHttpMessageConverter() {  
  24.         super(new MediaType("text""plain", DEFAULT_CHARSET), MediaType.ALL);  
  25.         this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());  
  26.     }  
  27.   
  28.     /** 
  29.      * Indicates whether the {@code Accept-Charset} should be written to any outgoing request. 
  30.      * <p>Default is {@code true}. 
  31.      */  
  32.     public void setWriteAcceptCharset(boolean writeAcceptCharset) {  
  33.         this.writeAcceptCharset = writeAcceptCharset;  
  34.     }  
  35.   
  36.     @Override  
  37.     public boolean supports(Class<?> clazz) {  
  38.         return String.class.equals(clazz);  
  39.     }  
  40.   
  41.     @Override  
  42.     protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {  
  43.         Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());  
  44.         return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));  
  45.     }  
  46.   
  47.     @Override  
  48.     protected Long getContentLength(String s, MediaType contentType) {  
  49.         Charset charset = getContentTypeCharset(contentType);  
  50.         try {  
  51.             return (long) s.getBytes(charset.name()).length;  
  52.         }  
  53.         catch (UnsupportedEncodingException ex) {  
  54.             // should not occur  
  55.             throw new InternalError(ex.getMessage());  
  56.         }  
  57.     }  
  58.   
  59.     @Override  
  60.     protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {  
  61.         if (writeAcceptCharset) {  
  62.             outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());  
  63.         }  
  64.         Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());  
  65.         FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));  
  66.     }  
  67.   
  68.     /** 
  69.      * Return the list of supported {@link Charset}. 
  70.      * 
  71.      * <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses. 
  72.      * 
  73.      * @return the list of accepted charsets 
  74.      */  
  75.     protected List<Charset> getAcceptedCharsets() {  
  76.         return this.availableCharsets;  
  77.     }  
  78.   
  79.     private Charset getContentTypeCharset(MediaType contentType) {  
  80.         if (contentType != null && contentType.getCharSet() != null) {  
  81.             return contentType.getCharSet();  
  82.         }  
  83.         else {  
  84.             return DEFAULT_CHARSET;  
  85.         }  
  86.     }  
  87.   
  88. }  

 

2.context配置

Xml代码  收藏代码
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"  
  3.     xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  6.                                                           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  7.                                                           http://www.springframework.org/schema/context   
  8.                                                           http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  9.                                                           http://www.springframework.org/schema/aop   
  10.                                                           http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
  11.                                                           http://www.springframework.org/schema/tx   
  12.                                                           http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
  13.                                                           http://www.springframework.org/schema/mvc   
  14.                                                           http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
  15.                                                           http://www.springframework.org/schema/context   
  16.                                                           http://www.springframework.org/schema/context/spring-context-3.1.xsd">  
  17.   
  18.   
  19.     <mvc:annotation-driven>  
  20.         <mvc:message-converters>  
  21.             <bean class="yourpackage.UTF8StringHttpMessageConverter" />  
  22.         </mvc:message-converters>  
  23.     </mvc:annotation-driven>  
  24.   
  25. ......  
  26.       
  27. </beans>  
0 0