关于Sping MVC 的 @ResponseBody 乱码问题的完美解决
重写了StringHttpMessageConverter 类,如下
package org.springframework.http.converter; 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.util.FileCopyUtils; /** * 通过重写解决了乱码问题 * * @author jiulong_ck * */ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); // 在这里先写好自己使用的默认编码 private final List<Charset> availableCharsets; private boolean writeAcceptCharset = true; public StringHttpMessageConverter() { super(new MediaType[] { new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL }); this.availableCharsets = new ArrayList(Charset.availableCharsets().values()); } 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 { Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset)); } protected Long getContentLength(String s, MediaType contentType) { Charset charset = getContentTypeCharset(contentType); try { return Long.valueOf(s.getBytes(charset.name()).length); } catch (UnsupportedEncodingException ex) { throw new InternalError(ex.getMessage()); } } protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException { if (this.writeAcceptCharset) { outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets()); } // 重新定义 MediaType ,解决乱码 /****************************/ MediaType contentType = outputMessage.getHeaders().getContentType(); Charset contentTypeCharset = getContentTypeCharset(contentType); contentType = new MediaType(contentType.getType(), contentType.getSubtype(), contentTypeCharset); outputMessage.getHeaders().setContentType(contentType); /****************************/ Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType()); FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset)); } protected List<Charset> getAcceptedCharsets() { return this.availableCharsets; } private Charset getContentTypeCharset(MediaType contentType) { if ((contentType != null) && (contentType.getCharSet() != null)) { return contentType.getCharSet(); } return DEFAULT_CHARSET; } }