去除Spring @ResponseBody产生的大量Accept-Charset

本贴最后更新于 2872 天前,其中的信息可能已经水流花落

Spring MVC使用@ResponseBody后会产生很大的响应头(Accept-Charset会达到4K+),原因在于默认情况下StringHttpMessageConverter.writeInternal()会将所有可用字符集回写到response响应头中:

 

去除这些信息我们可以这样,定义一个拦截器:

 

package cn.krun.cup.pojo;

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;

public class UTF8StringHttpMessageConverter extends
AbstractHttpMessageConverter<String> {

public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

private final List&lt;Charset&gt; availableCharsets;

private boolean writeAcceptCharset = true;

public UTF8StringHttpMessageConverter() {
	super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL);
	this.availableCharsets = new ArrayList&lt;Charset&gt;(Charset
			.availableCharsets().values());
}

/**
 * Indicates whether the {@code Accept-Charset} should be written to any
 * outgoing request.
 * &lt;p&gt;
 * Default is {@code true}.
 */
public void setWriteAcceptCharset(boolean writeAcceptCharset) {
	this.writeAcceptCharset = writeAcceptCharset;
}

@Override
public boolean supports(Class&lt;?&gt; 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}.
 * &lt;p&gt;
 * By default, returns {@link Charset#availableCharsets()}. Can be
 * overridden in subclasses.
 * 
 * @return the list of accepted charsets
 */
protected List&lt;Charset&gt; getAcceptedCharsets() {
	return this.availableCharsets;
}

private Charset getContentTypeCharset(MediaType contentType) {
	if (contentType != null &amp;&amp; contentType.getCharSet() != null) {
		return contentType.getCharSet();
	} else {
		return DEFAULT_CHARSET;
	}
}

}

 

然后在spring中配置

	<mvc:annotation-driven>
		<mvc:message-converters>
			<bean class="cn.krun.cup.pojo.UTF8StringHttpMessageConverter">
				<property name="writeAcceptCharset" value="false">
				</property>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>

 

Done!

 

 

 

 

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 88250

    @noah 嗯,3.2.9 也没有这个情况

  • 其他回帖
  • viruscamp

    应该不用自定义 class 的吧,配置文件改改就行了

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

    或者

    <mvc:annotation-driven>
    	<mvc:message-converters>
    		<bean class="org.springframework.http.converter.StringHttpMessageConverter">
    			<property name="supportedMediaTypes" value="text/plain;charset=UTF-8" />
    			<property name="writeAcceptCharset" value="false" />
    		</bean>
    	</mvc:message-converters>
    </mvc:annotation-driven>
    
  • melon
    作者

    @noah 我的版本是 4.0.1.RELEASE 😄

  • noah

    spring 哪个版本?我的 3.2 没有这种情况

  • 查看全部回帖

推荐标签 标签

  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 251 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    126 引用 • 1699 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 25 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 1 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 429 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 455 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 27 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 687 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    6558 引用 • 29450 回帖 • 246 关注
  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    20 引用 • 245 回帖 • 228 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 23 回帖 • 686 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    19 引用 • 31 回帖 • 6 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    123 引用 • 168 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 25 关注
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    4 引用 • 16 回帖 • 1 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    20 引用 • 74 回帖 • 2 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 24 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 345 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    21 引用 • 58 回帖
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 549 关注
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 6 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 2 关注