这个问题真是让我心力憔悴了...在客户现场对接就是乱码,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. HTML5小游戏之见缝插针

    今天给大家带来的就是一款叫做<见缝插针>的游戏.有空你就往里插,直到你无处可插!看你能过多少关! 简洁大气 黑白搭配游戏画面非常的简洁,米白色的背景中央,放置着一个不断旋转的太阳状的球体, ...

  2. sqlserver2008存储过程(比较两个日期大小和获取当前月最大天数的存储过程)

    下面简单介绍sqlserver2008两个常用的存储过程 1.比较两个日期大小的存储过程 2.获取当前月份的最大天数的存储过程 1.创建比较两个日期大小的存储过程 1)创建比较两个日期大小的存储过程 ...

  3. Unity3D 5.x 交互功能 - 碰撞检测函数

    1,给第一人称控制器添加脚本:playercollisions.js 脚本中只定义变量,先不添加方法: #pragma strict var door_open_time:float=3.0; var ...

  4. AngularJS Directive 隔离 Scope 数据交互

    什么是隔离 Scope AngularJS 的 directive 默认能共享父 scope 中定义的属性,例如在模版中直接使用父 scope 中的对象和属性.通常使用这种直接共享的方式可以实现一些简 ...

  5. JavaScript面向对象与原型

    工厂模式:无法识别对象 function createObject(name, age) { //集中实例化的函数 var obj = new Object(); obj.name = name; o ...

  6. JavaScript强化教程 —— Cocos2d-JS的屏幕适配方案

    1. 设置屏幕适配策略(Resolution Policy) 如果你还没有用过Resolution Policy,只需要在游戏载入过程完成之后(cc.game.onStart函数回调中),调用下面的代 ...

  7. 基于WebGL的三维地形渲染

    1.生成WebMap页面 #!/usr/bin/env python # -*- coding: utf-8 -*- import subprocess from jinja2 import Envi ...

  8. SharePoint 2013 Designer系列之数据视图

    在SharePoint使用中,数据展示是一块很重要的部分,很多时候我们会采用webpart的形式,但是有一些情况,我们不必使用开发,仅需使用Designer即可,下面让我简单介绍下数据视图的使用. 1 ...

  9. KVC&&&KVO

    KVC 什么是KVC --->What KVC指的就是NSKeyValueCoding非正式协议. KVC是一种间接地访问对象的属性的机制. 这种间接表现在通过字符串来标识属性,而不是通过调用存 ...

  10. oc 中组合排序算法

    - (NSMutableArray *)zuHeSuanFa:(NSMutableArray *)array chooseCount:(int)m { int n = (int)[array coun ...