文档章节

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

北风其凉
 北风其凉
发布于 2017/06/26 16:22
字数 602
阅读 98
收藏 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字符串作为中间介质通信的系统,双方使用的序列化和反序列化类尽量保持一致,以免在反序列化过程中触发不必要的麻烦。

© 著作权归作者所有

共有 人打赏支持
北风其凉

北风其凉

粉丝 115
博文 498
码字总数 463468
作品 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反序列化漏洞系列之–PHP序列化和反序列化原理

0.前言 本文为笃行日常学习记录,web安全php漏洞系列。 对象的序列化和反序列化作用就不再赘述,php中序列化的结果是一个php自定义的字符串格式,有点类似json. 我们在任何语言中设计对象的序列...

fobnn
08/27
0
0
PHP多种序列化/反序列化的方法

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

京牛教育科技
2016/08/27
9
2

没有更多内容

加载失败,请刷新页面

加载更多

Redis异构集群之间数据迁移方案

一、Redis集群迁移工具 最近在做Redis数据迁移,网上找了两款开源的Redis迁移工具。 第一种:redis-port Codis官方提供的一个工具,redis-port是一个Redis工具,通过解析rdb文件,实现Redis...

IT--小哥
16分钟前
1
0
MySQL5.7源码安装

5、MySQL源码安装(centos7.5) 5.1 下载软件 官方自带(boost版本mysql) wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.20.tar.gz tar xf mysql-boost-5.7.20.tar.g......

hnairdb
20分钟前
1
0
解压zip包(zip4j)

1:引入zip4j_1.3.2.jar 2:源码如下: package test;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List;import net.lingal......

uug
23分钟前
1
0
MySQL 8在CentOS 7用rpm安装

1.配置MySQL yum安装源和安装: #配置MySQL5.7的安装源 #https://repo.mysql.com/mysql57-community-release-el7.rpm #https://repo.mysql.com/mysql57-community-release-el7-11.noarch.rp......

MichaelShu
29分钟前
1
0
docker 安装zookeeper

1.下拉镜像: docker pull zookeeper 2.运行镜像: docker run --name myZookeeper --restart always -d zookeeper 此时,2181 2888 3888分别是zookeeper的(客户端端口,跟随端口,选择端口)...

狼王黄师傅
30分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部