Loading... > 今天你CRUD了吗? giao,最近跟其他项目对接老是要用json,什么解析json字符串,什么对象转json格式字符串,听着阿夜我真是头秃。 说起Java操作json,第一个映入我眼眶的不是阿里爸爸的fastjson,而是json-lib。接触这个是去年刚进公司时从前辈遗留的代码中看到的(失误失误前辈健在,只是头发快没了,说起这个话我不由得摸了摸头皮)。 当时觉得真好用呐,它的maven配置是这样的: ```xml <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> ``` 操作数据是这样的: ```java public static void main(String[] args) { String jsonStr = "{\"id\":1,\"name\":\"eknown\"}"; // json字符串转json对象 JSONObject obj = JSONObject.fromObject(jsonStr); // 操作json对象 System.out.println(obj.get("id")); obj.element("roleList", "[1,2,3]"); // json对象转json字符串 System.out.println(obj.toString()); } ``` 但是今天查阅资料的时候发现有文章提到json-lib有这样一个问题:在json字符串数据较大时,由于json-lib会对当前解析位置到字符串末尾进行substring操作,在JDK1.7以上的环境中,会进行大量的字符串复制操作,导致大量的CPU和内存消耗,严重的甚至会Full GC。 参考:https://www.cnblogs.com/mayswind/p/9222245.html 吓得夜仔我当场差点休克——我负责的三个已上线的项目,都使用了json-lib来解析字符串,甚至,在某个接口中,进行了非常多的json解析操作。ヽ(*。>Д<)o゜ 以后还是改用更快更省内存的json库吧,比如fastjson,听这名字就很快呐! Giao,但是fastjson前阵子不是爆出一堆严重漏洞嘛? 原谅夜仔我久居深山老林、每日CRUD,不问外间事。 幸好幸好,那帮猿已经紧急修复了漏洞了,只要将版本升级到1.2.60及以上就可以啦! ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.60</version> </dependency> ``` 这里给出一个简单的示例,毕竟夜我这帅都是每天枸杞泡茶保养的效果啦,不能熬夜哦。 ```java package jsonparse; import com.alibaba.fastjson.JSONObject; /** * @author zhangfanghao * @version 1.0 * @date 2019-12-17 20:04 */ public class FastJsonParseDemo { public static void main(String[] args) { String jsonStr = "{\"id\":1,\"name\":\"eknown\"}"; // json字符串转json对象 JSONObject obj = JSONObject.parseObject(jsonStr); // 操作json对象 System.out.println(obj.get("id")); obj.put("roleList", "[1,2,3]"); // json对象转json字符串 System.out.println(obj.toString()); // json对象转Java对象 User user = obj.toJavaObject(User.class); System.out.println(user); } } class User { private Integer id; private String name; private Object roleList; @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", roleList=" + roleList + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Object getRoleList() { return roleList; } public void setRoleList(Object roleList) { this.roleList = roleList; } } ``` 推荐阅读Java3y的这篇文章:https://juejin.im/post/5df2ecdaf265da33c7550328,里面讲得很好啦。 其实还有很多也很好用的json库呀,比如谷歌的Gson,又或者JSON In Java。 可惜,这些妖艳货暂时还不入不了夜的眼,等我有空再关门研究一下:sunglasses: --- 更新2019.12.18 giao,夜仔今天上班偷偷研究了一下json-lib操作json字符串和java对象互相转换,然后发现了一个问题: 如果一个class文件下有多个class,而其中那个不是public的class正好是要转换的java对象,比如这样: ```java public class TestJson { public static void main(String[] args) { User user = new User(1, "eknown"); JSONObject jsonObject = JSONObject.fromObject(user); } } class User { private Integer id; private String name; // 省略get/set方法,构造器 } ``` 报错: ```properties Exception in thread "main" net.sf.json.JSONException: java.lang.NoSuchMethodException: Property 'name' has no getter method in class 'class com.example.User' ``` 把这个user类改成TestJson类的静态内部类,再试一下,相同的报错。 然后把user移出来,作为一个单独的class文件,就正常了! 测试一下fastjson会不会也有这种情况: ```java public class FastJsonTest { public static void main(String[] args) { User user = new User(1, "eknown", true); JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(user)); System.out.println(jsonObject.toString()); User newUser = JSONObject.toJavaObject(jsonObject, User.class); System.out.println(newUser); } } class User { private Integer id; private String name; private Boolean enable; // 省略构造器、get和set方法 } ``` 测试结果: 1. user类是测试类的静态内部类,相互转换正常 2. user类是测试类所在class文件下的非public类,相互转换也正常 giao! net.sf.json-lib这么多锅。。帅夜我算是长见识了。 Last modification:December 19, 2019 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 请作者喝杯肥宅快乐水吧!
2 comments
长知识了
狗哥今天怎么有闲心看我博客