• 令人崩溃的@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的数据了).

  • 相关阅读:
    rgw
    comm命令
    s3cmd、aws的使用
    【RPM包的制作】
    【C++高级编程 | 23】future、packaged_task等使用机制
    【shell语法 | 01】基础练习
    【宏 | 01】#、##、__VA_ARGS__和##__VA_ARGS__的作用
    求求你别再用offset和limit分页了
    你和阿里程序员的差距在哪里?看看鸿蒙级计算机底层知识总结与操作系统就知道了
    什么?CPU 怎么运行代码?太刁难人了吧!
  • 原文地址:https://www.cnblogs.com/chyu/p/5517788.html
Copyright © 2020-2023  润新知