令人崩溃的@requestBody乱码一例

这个问题真是让我心力憔悴了...在客户现场对接就是乱码,StringHttpConverter怎么配置都不行...

场景其实很简单:客户那头post一个http请求,包体是json字符串,我这头spring项目用的@requestBody接收的这个json字符串,结果中文居然是乱码.

客户那头用的是个老系统自己封装的http发送类,他们自己系统之间接收发送的时候都是ok的,没有出现过乱码.所以客户侧是一脸无辜的看着我...我当时也是蒙了...

客户侧发送代码关键部分如下:

            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setAllowUserInteraction(true);
            connection.setRequestProperty("content-type", "text/html");
            connection.connect();
            outputStream = connection.getOutputStream();
            writer = new OutputStreamWriter(outputStream,"GBK");
            writer.write(requestXML);
            writer.flush();
            writer.close();

一看输出流已经显式的指定为gbk编码了,按理说我这头StringHttpConverter配置成GBK编码就应该是ok的,但是无论我怎么配置都是乱码..说实话此时我有点蒙了..所以进入了一个误区,我认为是StringHttpConverter没有配置生效,由于某些未知原因,所以我主要把精力放在换成几种不同的配置方法上挨个试验,看看是否可行.当然这只是在浪费时间.

后来我干脆直接自定义个StringHttpConver类,然后直接将其默认编码改为GBK,然后测试居然依然乱码,这就有点奇怪了,然后我跟踪了一下关键代码点:

@Override
    protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
        Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
        return StreamUtils.copyToString(inputMessage.getBody(), charset);
    }

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

然后标红的地方返回的是ISO-8859-1编码,这就让我震惊了.回头看了一下客户的发送代码:

connection.setRequestProperty("content-type", "text/html");

并没有指定编码,然后问题就明了了,用户没有指定content-type编码,然而这里并未是无编码而是采用默认的iso-8859-1编码,而spring的StringHttpConverter是先取content-type中的编码,没取到时才用默认的编码.这就导致无论我的StringHttpConverter怎么设置编码,由于请求中content-type是iso-8859-1,所以接收到的数据都是按照iso-8859-1来解码,而实际上数据是按照gbk编码,因而产生乱码..

解决方法也好办了:

1.客户的发送方法稍微改一下,这个方式是最好的:

connection.setRequestProperty("content-type", "text/html;charset=GBk");

2.如果发送方无论如何都没法改,只能服务器端处理的时候,要么所有接收到的数据都 new String(data.getByte("iso-8859-1"),"GBK"),要么直接自定义StringHttpConverter,将readInternal方法中的charset获取改为不先从请求头中读取,直接硬编码为GBK(当然这样做的后果就是只能接收GBK的数据了).

时间: 2024-08-22 06:27:27

令人崩溃的@requestBody乱码一例的相关文章

一次网站停止访问的问题解决过程,原因令人崩溃

最近对单位网站进行了改版,在本机和测试服务器测试了很久都没有问题,于是今天就部署到服务器上线了.同时.net framework版本由2.0升级到4.0.部署完测试了一下,没问题,就放出来了.一公布,大家纷纷点击.不一会儿,有人报告说访问不了了.一试,果然.大家赶紧到服务器查看,没发现什么异常.过了一会又好了.正当大家莫名奇妙时,又访问不了了,大家首先判断是不是程序池满了,但是很快发现同一个服务器上的其他网站也打不开,这些网站并不是同一个程序池.然后在服务器上访问了一下,可以打开.又利用其他ip

request、response 中文乱码问题与解决方式

request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: 乱码产生的原因:不管是request乱码还是response乱码,其实都是由于客户端(浏览器)跟服务器端采用的编码格式不一致造成的.以request乱码为例:浏览器向服务器发送请求,因为浏览器与服务器之间的通信实质上是socket流,所以要先将请求参数(字符)转换成字节,也就是编码过程,服务器接收到请求

C指针典例

C指针典例 2015-03-10 李海沿 一.指针的算术运算 例一. 1. char a[20]; 2. int *ptr=a; 3. ptr++; 在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整形变量a.接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4.由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节.由于char类型的长度是一个字节

单例初始化(MRC模式之autorelease)

最近在一项目中,在某个地方总是有内存闪退问题,经排查之后,终于找到问题所在. 项目中崩溃的地方使用单例写的(MRC模式),其中单例的初始化方法如下: + (GetCalendarEvents *)shareInstence { if (_get == nil) { _get = [[[GetCalendarEvents alloc] init] autorelease]; _get.projectPlanArray = [[[NSMutableArray alloc] init] autorel

java中文乱码解决之道(四)—–java编码转换过程

原文出处:http://cmsblogs.com/?p=1475 前面三篇博客侧重介绍字符.编码问题,通过这三篇博客各位博友对各种字符编码有了一个初步的了解,要了解java的中文问题这是必须要了解的.但是了解这些仅仅只是一个开始,以下博客将侧重介绍java乱码是如何产生的.存在哪些乱码的情况.该如何从根本上解决乱码问题.各位随博主一起征服令人厌烦的java乱码问题吧!!! java编码转换过程 我们总是用一个java类文件和用户进行最直接的交互(输入.输出),这些交互内容包含的文字可能会包含中文

解决Linux终端乱码的两则例子

现象描述 我们先来说一下出现乱码的原因. 例子 先举个实际的例子,我们一般通过ssh远程到服务器上进行操作.当在终端上执行一些有输出的任务时,就遇到乱码了. 比如,我登陆上oracle数据库服务器上,查看oracle RAC的状态: 比如上面的例子,除了英文字母外其它的都成了乱码了. 当然这个与运行什么程序没有什么关系,你可以试一下系统自带的命令,当参数错误时也会也现乱码. 当我们在网上找问题的解决方法时,有让你修改配置文件的,有让你修改环境变量的,有让你换个客户端的,还有让你装语言包的. 有这

java中文乱码解决之道(四)-----java编码转换过程

前面三篇博客侧重介绍字符.编码问题,通过这三篇博客各位博友对各种字符编码有了一个初步的了解,要了解java的中文问题这是必须要了解的.但是了解这些仅仅只是一个开始,以下博客将侧重介绍java乱码是如何产生的.存在哪些乱码的情况.该如何从根本上解决乱码问题.各位随博主一起征服令人厌烦的java乱码问题吧!!! java编码转换过程 我们总是用一个java类文件和用户进行最直接的交互(输入.输出),这些交互内容包含的文字可能会包含中文.无论这些java类是与数据库交互,还是与前端页面交互,他们的生命

jsp:中文乱码解决

说明:request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: 乱码产生的原因:不管是request乱码还是response乱码,其实都是由于客户端(浏览器)跟服务器端采用的编码格式不一致造成的.以request乱码为例:浏览器向服务器发送请求,因为浏览器与服务器之间的通信实质上是socket流,所以要先将请求参数(字符)转换成字节,也就是编码过程,服务器接收

(转)request和response的中文乱码问题

request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符, 服务器获取到的请求参数的值是乱码; response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码; 乱码产生的原因:不管是request乱码还是response乱码,其实都是由于客户端(浏览器)跟服务器端采用的编码 格式不一致造成的. 以request乱码为例:浏览器向服务器发送请求,因为浏览器与服务器之间的通信实质上是socket流,所以要先 将请求参数(字符)转换成字节,也就是编码过程,服务器接