文档章节

spring mvc3.1 @ResponseBody注解生成大量Accept-Charset

独钓渔
 独钓渔
发布于 2017/09/08 17:21
字数 666
阅读 33
收藏 1

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">
            </property></bean>
        </mvc:message-converters>
</mvc:annotation-driven>

 

 

 

二:

<!-- 默认的注解映射的支持 -->
	<mvc:annotation-driven>
		<mvc:message-converters register-defaults="true">
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
      			<property name="supportedMediaTypes">
	      			<list>  
	                    <value>text/plain;charset=UTF-8</value>
	                    <value>text/html;charset=UTF-8</value>
	                    <value>application/json;charset=UTF-8</value>
	                    <value>application/x-www-form-urlencoded; charset=UTF-8</value>
	               </list>
               </property>
               <property name="writeAcceptCharset" value="false" />
    		</bean>
   		</mvc:message-converters>
	</mvc:annotation-driven>

 

可以直接在springmvc中配置wirteAcceptCharset为 false。
springmvc中使用@responseBody注解返回中文乱码是可以配置上面的的 "supportedMediaTypes"。

 

(2)

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >  
    <property name="messageConverters">   
        <list>   
            <bean class = "org.springframework.http.converter.StringHttpMessageConverter">   
                <property name = "supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>   
                    </list>   
                </property>   
                <property name="writeAcceptCharset" value="false" />
            </bean>   
        </list>   
   </property>  
</bean>

注意,需要把这段放在xxx-servlet.xml中<context:component-scan base-package="xxxxx"/>前面哦~

 

三:

如果不是使用注解还可以使用

response.setContentType("application/json; charset=UTF-8");

response.setCharacterEncoding("utf-8"); 

这个在springmvc和servlet中都可以直接使用。

 

 

 

总结:这也是处理@responseBody注解返回中文乱码的处理方式

1,通过配置”supportedMediaTypes“为指定编码格式。即第二种方法。

2,继承StringHttpMessageConverter转换类
因为StringHttpMessageConverter类中默认的文本类型是‘ISO-8859-1’,我们是想把这个类型替换掉,而这个默认值是private final的。所以我们只有继承该类,并用继承类代替该转换类。这个就是第一种方法。

 

本文转载自:http://blog.csdn.net/sunshine_bean/article/details/40192253

共有 人打赏支持
独钓渔
粉丝 47
博文 375
码字总数 142587
作品 0
沙坪坝
系统管理员
私信 提问
【转】Ajax响应中文乱码 [SpringMVC使用@ResponseBody处理Ajax请求]

Spring3.0 MVC @ResponseBody 的作用是把返回值直接写到HTTP response body里。 Spring使用AnnotationMethodHandlerAdapter的handleResponseBody方法, AnnotationMethodHandlerAdapter使用r......

一堆BUG
2013/09/10
0
0
Spring MVC ResponseBody

上一节小博老师跟大家一起学习了RequestBody注解的适用情况,了解了在什么情况下使用以及如何使用RequestBody注解。这一节小博老师继续给大家讲解Controller方法上的另一个注解ResponseBody。...

博为峰教研组
2016/12/07
30
0
认识HttpMessageConverter

DispatcherServlet默认装配一下几个HandlerAdapters RequestMappingHandlerAdapter中默认装载了以下几个HttpMessageConverter public RequestMappingHandlerAdapter() {StringHttpMessageCo......

灯下草虫鸣_
2018/07/12
0
0
spring web 4.1处理json

Spring mvc处理json,我们都知道使用@ResponseBody,处理xml也是用此注解。如果想spring mvc的使用@ResponseBody注解处理json,我们需要加入一些处理bean,也可以使用默认spring提供的。 通过...

引鸩怼孑
2015/07/09
0
0
SpringMVC 返回中文字符串时乱码

SpringMVC的@ResponseBody注解可以将请求方法返回的对象直接转换成JSON对象,但是当返回值是String的时候,中文会乱码,原因是因为其中字符串转换和对象转换用的是两个转换器,而String的转换...

费氏家族
2017/10/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

iOS个人中心渐变动画、微信对话框、标签选择器、自定义导航栏、短信验证输入框等源码

iOS精选源码 简单的个人中心页面-自定义导航栏并予以渐变动画 程序员取悦女票的正确姿势---Tip1(iOS美容篇) iOS 前台重启应用和清除角标的问题 微信原生提醒对话框3.0 JHLikeButton - 有趣...

Android爱开源
6分钟前
0
0
Yii2使用驼峰命名的形式访问控制器

yii2在使用的时候,访问控制器的时候,如果控制器的名称是驼峰命名法,那访问的url中要改成横线的形式。例如: public function actionRoomUpdate(){//}//访问的时候就要www.test.co...

dragon_tech
9分钟前
0
0
Navicat使用教程:使用Navicat Query Analyzer优化查询性能(第2部分)

下载Navicat Monitor最新版本 Navicat Monitor 是一套安全、简单而且无代理的远程服务器监控工具。它具有强大的功能使你的监控发挥最大效用。受监控的服务器包括 MySQL、MariaDB 和 Percona ...

电池盒
16分钟前
0
0
Python3 读写utf-8文本文件

with open('testRead.txt', 'r', encoding='utf-8') as f: for each_line in f: Passwith open('testWrite.txt', 'w', encoding='utf-8') as f: f.write('写入的内容'......

编程老陆
19分钟前
0
0
Linux syslog相关函数详解

介绍 syslog是Unix系统的日志系统。可以将日志记录在本地系统中。 一个完整的syslong日志包含如下信息:程序模块 | 严重性 | 时间 | 主机名 | 进程名 | 进程ID | 正文。 syslong相关函数 1....

RongJinhui0
23分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部