springmvc3.0使用@ResponseBody返回参数乱码
阅读(344)
2017-12-06
使用@ResponseBody注解返回的json数据乱码。用户网络上大多数贴都是springmvc3.0以上版本,试了很多办法都不行。只能来点简单粗暴的办法。
发现原因
使用<mvc:annotation-driven />,Spring的StringHttpMessageConverter默认配置是ISO-8859-1的。如下图源代码片段所示:
1 2 3 4 5 6 | public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { public static final Charset DEFAULT_CHARSET = Charset.forName( "ISO-8859-1" ); private final List<Charset> availableCharsets = new ArrayList(Charset.availableCharsets().values()); private boolean writeAcceptCharset = true ; ... } |
调试返回情况如下图:
1 | {data: "", message: "????", success: 0} |
解决办法
快刀斩乱麻
第一步:
查看spring的StringHttpMessageConverter的源码,自定义StringHttpMessageConverter类,继承AbstractHttpMessageConverter<String>修改默认编码为UTF-8。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | package com.weizhixi.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.FileCopyUtils; 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; /** * Created by cxq on 2017/12/6. */ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { public static final Charset DEFAULT_CHARSET = Charset.forName( "UTF-8" ); private final List<Charset> availableCharsets = new ArrayList(Charset.availableCharsets().values()); private boolean writeAcceptCharset = true ; public StringHttpMessageConverter() { super ( new MediaType[]{ new MediaType( "text" , "plain" , DEFAULT_CHARSET), MediaType.ALL}); } public void setWriteAcceptCharset( boolean writeAcceptCharset) { this .writeAcceptCharset = writeAcceptCharset; } public boolean supports(Class<?> clazz) { return String. class .equals(clazz); } protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException { MediaType contentType = inputMessage.getHeaders().getContentType(); Charset charset = contentType.getCharSet() != null ?contentType.getCharSet():DEFAULT_CHARSET; return FileCopyUtils.copyToString( new InputStreamReader(inputMessage.getBody(), charset)); } protected Long getContentLength(String s, MediaType contentType) { if (contentType != null && contentType.getCharSet() != null ) { Charset charset = contentType.getCharSet(); try { return Long.valueOf(( long )s.getBytes(charset.name()).length); } catch (UnsupportedEncodingException var5) { throw new InternalError(var5.getMessage()); } } else { return null ; } } protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException { if ( this .writeAcceptCharset) { outputMessage.getHeaders().setAcceptCharset( this .getAcceptedCharsets()); } MediaType contentType = outputMessage.getHeaders().getContentType(); Charset charset = contentType.getCharSet() != null ?contentType.getCharSet():DEFAULT_CHARSET; FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset)); } protected List<Charset> getAcceptedCharsets() { return this .availableCharsets; } } |
第二步:
弃用<mvc:annotation-driven />,加上2个配置。注意messageConverters使用刚刚自定义的StringHttpMessageConverter。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | < bean class = "org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" ></ bean > < bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > < property name = "messageConverters" > < list > < bean class = "com.weizhixi.converter.StringHttpMessageConverter" ></ bean > < bean class = "org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" > < property name = "supportedMediaTypes" > < list > < value >application/json;charset=UTF-8</ value > </ list > </ property > </ bean > </ list > </ property > </ bean > |
以上处理完毕!
尝试再访问下:
1 | {data: "", message: "请先登录", success: 0} |
已经正常返回了。
原创文章,转载请注明出处:https://www.weizhixi.com/article/21.html