springmvc3.0使用@ResponseBody返回参数乱码
阅读(342)
2017-12-06
使用@ResponseBody注解返回的json数据乱码。用户网络上大多数贴都是springmvc3.0以上版本,试了很多办法都不行。只能来点简单粗暴的办法。
发现原因
使用<mvc:annotation-driven />,Spring的StringHttpMessageConverter默认配置是ISO-8859-1的。如下图源代码片段所示:
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; ... }
调试返回情况如下图:
{data: "", message: "????", success: 0}
解决办法
快刀斩乱麻
第一步:
查看spring的StringHttpMessageConverter的源码,自定义StringHttpMessageConverter类,继承AbstractHttpMessageConverter<String>修改默认编码为UTF-8。
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。
<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>
以上处理完毕!
尝试再访问下:
{data: "", message: "请先登录", success: 0}
已经正常返回了。
原创文章,转载请注明出处:https://www.weizhixi.com/article/21.html