文档章节

记录一个JSON字符串反序列化问题

北风其凉
 北风其凉
发布于 2017/06/26 16:22
字数 602
阅读 76
收藏 0

最近工作中遇到一个问题,有A、B两个系统要进行通信。双方开发人员约定了一个类,A系统将数据填入类中,再将类序列化成JSON字符串,字符串传递到B系统后,B系统再反序列化此字符串,得到数据。在一次通信过程中,程序突然报错,提示反序列化失败,排查问题时发现,A、B两系统序列化和反序列化使用了不同的库。A系统使用fastjson进行序列化,B系统使用jackson进行反序列化,两个库在序列化JSON串时存在区别。

废话不多说,直接上代码。

首先明确下需要添加的引用:

fastjson:fastjson-1.1.26.jar

jackson:

1、jackson-annotations-2.2.1.jar

2、jackson-core-2.2.1.jar

3、jackson-core-asl-1.8.8.jar

4、jackson-databind-2.2.1.jar

5、jackson-mapper-asl-1.8.8.jar

6、jackson-module-jaxb-annotations-2.2.1.jar

现有类PersonInfo如下

public class PersonInfo {
    String name;
    String remark;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

测试场景有3:

1、使用fastjson对此类进行序列化,并打印序列化结果

2、使用jackson对此类进行序列化,并打印序列化结果

3、使用jackson对fastjson序列化后的字符串进行反序列化


import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;

import com.alibaba.fastjson.JSON;

public class MyProgram {

    public static void main(String args[]) {
        
        try {
            PersonInfo personInfo = new PersonInfo();
            personInfo.setName("Tsybius");
            personInfo.setRemark("[\t\r\n]");
            
            //使用fastjson序列化类
            String jsonString = JSON.toJSONString(personInfo);
            System.out.println(jsonString);

            System.out.println("-----------------------");

            //使用jackson序列化类
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
            
            String jsonString2 = mapper.writeValueAsString(personInfo);
            System.out.println(jsonString2);

            System.out.println("-----------------------");

            //使用jackson反序列化fastjson序列化结果(报错)
            mapper.readValue(jsonString, PersonInfo.class);

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
}

运行结果如下:

{"age":26,"bornDate":687944560794,"name":"Tsybius","remark":"[    \r\n]"}
-----------------------
{"name":"Tsybius","age":26,"bornDate":687944560794,"remark":"[\t\r\n]"}
-----------------------
Illegal unquoted character ((CTRL-CHAR, code 9)): has to be escaped using backslash to be included in string value
 at [Source: java.io.StringReader@6ebc05a6; line: 1, column: 64]

可以看到,fastjson将水平制表符当做字符处理,而jackson将水平制表符转义为\t处理,因此,使用jackson反序列化fastjson生成的JSON字符串时,直接报错。

结论:对于使用JSON字符串作为中间介质通信的系统,双方使用的序列化和反序列化类尽量保持一致,以免在反序列化过程中触发不必要的麻烦。

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 114
博文 497
码字总数 462457
作品 4
朝阳
程序员
httpclient提交json到tomcat,接收到的json却是不完整的

写了一个rest接口,接口接受json数据解析批量入索引。入索引的频率和大都挺大的,每天看日志都会有几条写入失败,原因是收到client端的数据不完整,是一个被截断的json。如图: 我是通过htt...

coder4j
2017/12/19
240
8
PHP多种序列化/反序列化的方法

序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性。 1. s...

cnu2m
2012/11/08
0
0
PHP 序列化变量的 4 种方法

序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性。 1. s...

mickelfeng
2013/01/12
0
1
PHP多种序列化/反序列化的方法

serialize和unserialize函数 这两个是序列化和反序列化PHP中数据的常用函数。 当数组值包含如双引号、单引号或冒号等字符时,它们被反序列化后,可能会出现问题。为了克服这个问题,一个巧妙...

京牛教育科技
2016/08/27
9
2
PHP多种序列化以及反序列化

PHP多种序列化以及反序列化 PHP点点通2016-09-2147 阅读 序列化PHP 序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个...

PHP点点通
2016/09/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

java并发备忘

不安全的“先检查后执行”,代码形式如下: if(条件满足){ //这里容易出现线程安全问题//doSomething}else{//doOther} 读取-修改-写入 原子操作:使用CAS技术,即首先从V中读取...

Funcy1122
今天
0
0
SpringBoot2.0 停机

最近新建了个SpringBoot2.0的项目,因为原来一直使用的是传统的Tomcat部署war包的形式,所以这次SpringBoot内置Tomcat部署jar包的时候遇到了很多问题。其中一个就是因为没有外置的Tomcat容器...

Canaan_
昨天
0
1
Confluence 6 外部参考

一个外部参考的意思是任何站点链接到你 Confluence 的实例。任何时候当 Confluence 的用户单击这个外部链接的时候,Confluence 可以记录这次单击为参考。 在默认的情况下,外部链接的参考链接...

honeymose
昨天
0
0
Android中的设计模式之抽象工厂模式

参考 《设计模式解析》 第十一章 Abstract Factory模式 《设计模式:可复用面向对象软件的基础 》3.1 Abstract Factory 抽象工厂 对象创建型模式 《Android源码设计模式解析与实战》第6章 创...

newtrek
昨天
0
0
Redis | 地理空间(GEO)的一个坑

Redis的地理空间(Geo)是个好东西,轻轻松松的就可以把地图描点的问题处理了, 最近却遇到一个坑...Redis采用的Msater-Slave模式, 运用GEORADIUS在salve读取对应的数据,新增了从节点但是从不返...

云迹
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部