这个问题真是让我心力憔悴了...在客户现场对接就是乱码,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的数据了).

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

  1. CVE-2013-1347:从入门到放弃之调试分析令人崩溃的 Microsoft IE CGenericElement UAF 漏洞

    0x01 2013 年 "水坑" APT 攻击事件 在 2013 年 5 月,美国的劳工部网站被黑,利用的正是 CVE-2013-1347 这个漏洞,在当时导致大量使用 IE8 访 ...

  2. “在注释中遇到意外的文件结束”--记一个令人崩溃的bug

    下午写程序,写的好好的,突然报错"在注释中遇到意外的文件结束". 下面是官方给出的错误原因是缺少注释终结器 (* /). // C1071.cpp int main() { } / ...

  3. SpringMVC RESTful中文乱码

    开发中常遇到各种中文乱码很少心烦,这里总结了各种中文乱码https://www.cnblogs.com/lwx521/p/9856186.html 下面以SpringMVC遇到的中文乱码为例详解 首先 ...

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

    前面三篇博客侧重介绍字符.编码问题,通过这三篇博客各位博友对各种字符编码有了一个初步的了解,要了解java的中文问题这是必须要了解的.但是了解这些仅仅只是一个开始,以下博客将侧重介绍java乱码是如何 ...

  5. jsp:中文乱码解决

    说明:request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: ...

  6. 解决ajax中文乱码问题

    主要遇到的问题: 一.ajax向服务器提交的数据有中文,没有设置编码方式.造成服务器接收到乱码 二.服务器向ajax返回数据中有中文,没有设置响应编码方式,造成ajax接收到乱码 乱码产生的原因:不管 ...

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

    request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码:   response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: ...

  8. request和response的中文乱码问题

    request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码:   ...

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

    原文出处:http://cmsblogs.com/?p=1475 前面三篇博客侧重介绍字符.编码问题,通过这三篇博客各位博友对各种字符编码有了一个初步的了解,要了解java的中文问题这是必须要了解的. ...

随机推荐

  1. SSL介绍与Java实例

    有关SSL的原理和介绍在网上已经有不少,对于Java下使用keytool生成证书,配置SSL通信的教程也非常多.但如果我们不能够亲自动手做一个SSL Sever和SSL Client,可能就永远也不能 ...

  2. 谈一谈.net析构函数对垃圾回收的影响

    之前忘了说了 代码都是在Release模式下运行的,现在补充上. 这里说析构函数,其实并不准确,应该叫Finalize函数,Finalize函数形式上和c++的析构函数很像 ,都是(~ClassNam ...

  3. 用Spring Boot颠覆Java应用开发

    Java开发概述: 使用Java做Web应用开发已经有近20年的历史了,从最初的Servlet1.0一步步演化到现在如此多的框架,库以及整个生态系统.经过这么长时间的发展,Java作为一个成熟的语言, ...

  4. Json to JObject转换的使用方法

    Linq to JSON是用来操作JSON对象的.可以用于快速查询,修改和创建JSON对象.当JSON对象内容比较复杂,而我们仅仅需要其中的一小部分数据时,可以考虑使用Linq to JSON来读取和 ...

  5. npm插件制作及发布基础教程

    最近有同事在搞npm插件,想用了这么久的npm也没有自己制作一个插件出来练一练,所以动手把之前的图片随手势移动的react组件改写成了npm插件,之前的博客地址http://www.cnblogs.c ...

  6. H5学习

    1.html{font-size:62.5%;}//不用font-size:10px的原因:(因为设了62.5%后就有1rem = 10px,便于用rem来指定元素的尺寸,这样响应式的时候可以直接改变 ...

  7. iOS之获取屏幕尺寸

    //app尺寸,去掉状态栏 CGRect appRect = [UIScreenmainScreen].applicationFrame; NSLog(@"%f, %f, %f,%f&quo ...

  8. ListView实现点击事件以及总结

    差点吓死我了,好不容易写的博客没有了,还好有自动保存功能,不然我真的是呜呜... ---恢复内容开始--- 开学一个月了,终于可以看见自己的作品雏形了. 从一个小白到现在半年了,觉得日子过得比较充实, ...

  9. js---OOP浅谈

    对象化编程-------简单地去理解就是把javascript能涉及到的范围分成各种对象,对象下面再次划分对象.编程出发点多是对象,或者说基于对象.所说的对象既包含变量,网页,窗口等等 对象的含义   ...

  10. va_start和va_end使用详解

    本文主要介绍va_start和va_end的使用及原理. 介绍这两个宏之前先看一下C中传递函数的参数时的用法和原理: 1.在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表 ...