最近工作中遇到一个问题,有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字符串作为中间介质通信的系统,双方使用的序列化和反序列化类尽量保持一致,以免在反序列化过程中触发不必要的麻烦。