Spring3 MVC使用@ResponseBody后会产生非常大的响应头(Accept-Charset会达到4K+)。原因在于默认情况下StringHttpMessageConverter.writeInternal()会将全部可用字符集回写到response响应头中:问题来了
解决方案:
一般我们都会重写springs mvc的HttpMessageConverter。改为utf-8编码:
package com.goldpalm.core.spring.mvc; 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; /** * 重写SpringMVC的字符串转换器。使用UTF-8编码 * @since 2012-7-5 下午2:28:19 * @author Jesse Lu */ 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); } @SuppressWarnings("rawtypes") @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; } } }
在xm中配置:注意红色圈起来的配置
<mvc:annotation-driven> <mvc:message-converters> <bean class="com.goldpalm.core.spring.mvc.UTF8StringHttpMessageConverter"> <property name="writeAcceptCharset" value="false" /> </bean> </mvc:message-