关于fastjson,gson,jackson的一个反序列化简单对比
测试字符串 (首先声明,这不是一个标准合格的json字符串)
String data="[ " +
"{id: 1, name: \"第一级1\", pid: 0}," +
"{id: 2, name: \"第一级2\", pid: 0}," +
"{id: 3, name: \"第二级1-3\", pid: 2}, " +
"{id: 4, name: \"第二级2-4\", pid: 2}, " +
"{id: 5, name: \"第三级1-5\", pid: 4}," +
"{id: 6, name: \"第一级3\", pid: 0}," +
"{id: 7, name: \"第二级1-7\", pid: 1}, " +
"{id: 8, name: \"第三级1-8\", pid: 7}, " +
"]";
java 实体类
public static class MenuTree{
int id;
String name;
int pid;
List<MenuTree> children;
public List<MenuTree> getChildren() {
return children;
}
public void setChildren(List<MenuTree> children) {
this.children = children;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
@Override
public String toString() {
return "{" +
"id=" + id +
", name='" + name + '\'' +
", pid=" + pid +
", children=" + children +
'}';
}
//构造函数
public MenuTree(int id, String name, int pid, List<MenuTree> children) {
this.id = id;
this.name = name;
this.pid = pid;
this.children = children;
}
}
测试结果是:
1,fastjson:(完美处理)尽管字符串各种不合规范,比如在[]前后无端的各种空格,key无双引号,连引号都没有。value也没有引号,实体类存在有参构造函数。通通无视。成功work,牛逼
//fastjson将json字符串转List对象(反序列化)
List<MenuTree> MenuList= JSONObject.parseArray(data,MenuTree.class);
//遍历list
MenuList.forEach(System.out::println);
//将List对象转json字符串(序列化)
System.out.println("fastjson: "+ JSON.toJSONString(MenuList, SerializerFeature.WriteMapNullValue));
fastjson效果:
2,gson(完美处理没有任何错误,可以看出gson的api设计也挺人性化的,但比fastjson多了一步new的操作。)
//Gson
Gson gson = new Gson();
//将json字符串转List对象(反序列化)
List<MenuTree> MenuList= gson.fromJson(data,new TypeToken<List<MenuTree>>() {}.getType());
//遍历list
MenuList.forEach(System.out::println);
//将List对象转json字符串(序列化)
System.out.println("GSON:"+gson.toJson(MenuList));
gson效果:
3,jackson(不用看我了,这活我干不了,哈哈!同样的字符串,不信大家去试,不管你加多少注解,你能把上面这段不完全合规的json字符不做修改用jackson序列化和反序列化一遍我跪地拜师)
我尝试过加了5-7个注解也无解,操作不了。
//无双引号
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//允许出现特殊字符和转义符
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ;
//允许出现单引号
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true) ;
mapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true) ;
同时还加了构造函数处理注解一堆。死活不行。
如果要使用jackson处理,要把上面的json字符串修改成下面这样( 这个是标准json格式了), 然后再 删除掉构造函数 才可以正常work,如果不删除构造函数会报这个错误(cannot deserialize from Object value (no delegate- or property-based Creator)
标准格式json字符串
String data="[" +
"{\"id\":1, \"name\":\"第一级1\", \"pid\":0}," +
"{\"id\":2, \"name\":\"第一级2\", \"pid\":0}," +
"{\"id\":3, \"name\":\"第一级1-3\", \"pid\":2}," +
"{\"id\":4, \"name\":\"第一级2-4\", \"pid\":2}," +
"{\"id\":5, \"name\":\"第一级1-5\", \"pid\":4}," +
"{\"id\":6, \"name\":\"第一级3\", \"pid\":0}," +
"{\"id\":7, \"name\":\"第一级1-7\", \"pid\":1}," +
"{\"id\":8, \"name\":\"第一级1-8\", \"pid\":7}" +
"]";
最后:喜欢用哪个用哪个,毕竟json字符串处理也很简单,我通常很多情况下都是手拼json,手转的,几乎不用json工具类。自己封装的转换类。说实话自己都没想到被很多知乎大鸟们吹的天晕地暗日月无光神奇无比的jackson,原来是这样的怂。哈哈哈。大跌眼镜!另外要说一下,默认情况下fastjson,序列化和反序列化出来顺序是乱的。因为内部使用了Hashmap。如果要保证顺序要加注解。比如:如果要反序列化保证顺序:有两种操作。
一,类头部加序列化顺序标识注解
//菜单树模型结构
@JSONType(orders={"id","name","pid","children"}) //fastjson序列化字段顺序注解
public static class MenuTree{}
二,在每个成员属性上单独添加@JSONField(ordinal = 1)注解
本文来自博客园,作者:IT情深,转载请注明原文链接:https://www.cnblogs.com/wh445306/p/16751757.html