Java基础系列16:使用JSONObject和JSONArray解析和构造json字符串
在Java开发中,我们通常需要进行XML文档或JSON字符串的构造和解析。当然在Java Web开发中有一些第三方插件是可以自动完成Java对象和json之间的转换的,比如:jackson插件(PS:关于jackson的基本使用可以参考下我以前写过的这篇文章:https://www.zifangsky.cn/380.html)。
不过为了能够更好地理解json字符串的构造和解析,我将使用JSON-lib包来手动完成对json的构造和一些基本方法的使用。JSON-lib包中最关键的两个类分别是JSONObject和JSONArray,我们可以简单地将JSONObject这个类构造的字符串理解成Map集合;将JSONArray这个类构造的字符串理解成List集合或者数组。当然,关于它们的一些基本使用我将在下面详细介绍
要想使用JSON-lib来完成json字符串的构造或者解析工作,除了需要json-lib-2.4-jdk15.jar这个jar包之外,还需要以下几个依赖jar包:
- commons-beanutils-1.9.2.jar
- commons-collections-3.2.2.jar
- commons-lang-2.4.jar
- commons-logging-1.1.3.jar
- ezmorph-1.0.6.jar
当然,这几个jar包可以自行百度下载,也可以使用我用过的这几个jar包:http://pan.baidu.com/s/1hrGhTek
(1)JSON字符串格式化:
在正式开始介绍json字符串的构造之前,我首先推荐一个在线的json格式化工具,可以将我们生成的json字符串格式化成比较直观的形式,便于我们查看,传送门:http://tool.oschina.net/codeformat/json
(2)JSON字符串的两种基本构造方法:
i)新建一个普通的Java工程,并导入上述的几个依赖包
ii)新建两个测试用的Java类:
Animal.java:
123456789101112131415161718192021222324252627282930313233 | package cn.zifangsky.json; public class Animal { private String name; private int age; public Animal() { } public Animal(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } |
User.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | packagecn.zifangsky.json; importjava.util.List; publicclassUser{ privateStringname; privateStringsex; privateintage; privateStringcontact; privateList<Animal>ownPet; publicUser(){ } publicUser(Stringname,Stringsex,intage,Stringcontact, List<Animal>ownPet){ this.name=name; this.sex=sex; this.age=age; this.contact=contact; this.ownPet=ownPet; } publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicStringgetSex(){ returnsex; } publicvoidsetSex(Stringsex){ this.sex=sex; } publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } publicStringgetContact(){ returncontact; } publicvoidsetContact(Stringcontact){ this.contact=contact; } publicList<Animal>getOwnPet(){ returnownPet; } publicvoidsetOwnPet(List<Animal>ownPet){ this.ownPet=ownPet; } } |
iii)一个json字符串构造实例:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 | package cn.zifangsky.json; import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map; import net.sf.json.JSONObject; public class JSONObjectDemo { /** * 使用Map集合生成json字符串 * */ public JSONObject createJsonFromMap(Map<String, String> jMap) { JSONObject jObject = new JSONObject(); jObject.putAll(jMap); return jObject; } /** * 使用一个Java对象生成json字符串 * */ public JSONObject createJsonFromObject(Object object) { return JSONObject.fromObject(object); } public static void main(String[] args) { JSONObjectDemo demo = new JSONObjectDemo(); Map<String, String> tMap = new HashMap<String, String>(); tMap.put("name", "zifangsky"); tMap.put("sex", "male"); tMap.put("age", "1024"); tMap.put("contact", "https://www.zifangsky.cn"); JSONObject jObject1 = demo.createJsonFromMap(tMap); System.out.println("createJsonFromMap: " + jObject1); System.out.println("***************************"); // ******************************************** User u = new User(); u.setName("AlphaGo"); u.setAge(10); Animal dog = new Animal("旺财", 5); Animal cat = new Animal("九头猫妖", 2); List<Animal> pets = new ArrayList<Animal>(); pets.add(dog); pets.add(cat); u.setOwnPet(pets); JSONObject jObject2 = demo.createJsonFromObject(u); System.out.println("createJsonFromObject: " + jObject2); }} |
输出如下:
1 2 3 | createJsonFromMap:{"sex":"male","contact":"https://www.zifangsky.cn","name":"zifangsky","age":"1024"} *************************** createJsonFromObject:{"ownPet":[{"name":"旺财","age":5},{"name":"九头猫妖","age":2}],"contact":"","sex":"","name":"AlphaGo","age":10} |
当然,我们可以看出现在这种json字符串的格式不是很友好,我们不能很直观的看出整个json的内在逻辑构成,因此需要对它进行格式化。在使用了我上面推荐的在线工具进行格式化之后,这两个json字符串分别是这样的:
123456 | { sex: "male", contact: "https://www.zifangsky.cn", name: "zifangsky", age: "1024"} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | { ownPet:[ { name:"旺财", age:5 }, { name:"九头猫妖", age:2 } ], contact:"", sex:"", name:"AlphaGo", age:10 } |
这样就可以很清晰的看出整个json字符串的构成了。当然,上面生成json的代码都很简单,自己看一下就明白了,我这里就不多说了
(1)JSONObject的put方法:
使用put方法可以在一个json中插入一个节点,如果该节点已经存在,那么该节点的值将会被替换
1234567891011121314151617181920212223 | /** * 使用put方法插入节点,如果该key下已经存在值则替换该值 * */ public JSONObject testPut() { JSONObject jObject = new JSONObject(); jObject.put("1", "put1"); jObject.put("2", "put2"); jObject.put("3", "put3"); Animal bird = new Animal("bird", 1); jObject.put("4", bird); List<String> list = new ArrayList<String>(); list.add("string1"); list.add("string2"); jObject.put("string", list); jObject.put("5", "put5"); jObject.put("2", "put6");// jObject.put("string", true); return jObject; } |
然后在主函数中调用执行该方法:
1 2 3 4 | JSONObjectDemo2demo2=newJSONObjectDemo2(); System.out.println("put: "+demo2.testPut()); System.out.println(); |
对输出的json字符串进行格式化之后,该json的格式如下所示:
123456789101112131415 | { 1: "put1", 2: "put6", 3: "put3", 4: { name: "bird", age: 1 }, 5: "put5", string: [ "string1", "string2" ]} |
(2)JSONObject的accumulate方法:
对于accumulate方法,如果节点不存在时,那么accumulate方法将和put方法一样在json中插入一个新节点;如果是一个已经存在的节点,那么将会在该节点上累积此次的值,形成一个数组的形式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /** * 使用accumulate方法可以在一个key下累积值 * 如果该key下存在值则值继续累积,形成一个数组 * 如果该key不存在则accumulate方法相当于put方法 * */ publicJSONObjecttestAccumulate(){ JSONObjectjObject=newJSONObject(); jObject.put("1","1"); jObject.put("2",2); jObject.put("3",3.3); jObject.accumulate("1","1.11"); jObject.accumulate("2",false); Animaldove=newAnimal("stupid dove",2); jObject.accumulate("2",dove); List<String>list=newArrayList<String>(); list.add("arr1"); list.add("arr2"); jObject.accumulate("2",list); jObject.accumulate("4","4"); returnjObject; } |
然后同样是在主函数中调用执行这个方法,最后对输出的json字符串进行格式化之后,该json的格式如下所示:
123456789101112131415161718192021 | { 1: [ "1", "1.11" ], 2: [ 2, false, { name: "stupid dove", age: 2 }, [ "arr1", "arr2" ] ], 3: 3.3, 4: "4"} |
(3)JSONObject的element方法:
据我所知,这个方法跟put方法的基本使用是一样的(PS:如果二者有使用不一样的,希望大家可以告诉我一下):
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * element方法跟put方法的使用基本一样 * */ publicJSONObjecttestElement(){ JSONObjectjObject=newJSONObject(); jObject.put("1","1"); jObject.put("2",2); jObject.element("2","2_element"); jObject.element("3","333"); returnjObject; } |
最后对输出的json字符串进行格式化之后,该json的格式如下所示:
12345 | { 1: "1", 2: "2_element", 3: "333"} |
(4)JSONArray的基本使用:
对于JSONObject和JSONArray这两个类,有的童鞋可能不是很明白二者的区别在哪里。其实很简单,JSONObject构造的字符串就像Map集合一样,是键值对的形式,即:Key:Value,多个键值对之间以英文逗号连接(PS:可以观察上面的那个json字符串)。于此同时,JSONArray构造的字符串就如List集合或者数组一样,是一个数组的形式,即:[array1,array2,array3 …]
比如说下面这个方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * JSONArray的基本使用 * 可以形成数组 * */ publicJSONObjecttestJSONArray(){ JSONObjectjObject=newJSONObject(); jObject.put("1","1"); jObject.put("2",2); jObject.put("3",3.3); JSONArrayjsonArray=newJSONArray(); jsonArray.add("arr1"); jsonArray.add("arr2"); jObject.put("array",jsonArray); returnjObject; } |
对输出的json字符串进行格式化之后,该json的格式如下所示:
123456789 | { 1: "1", 2: 2, 3: 3.3, array: [ "arr1", "arr2" ]} |
从上面的json字符串可以看出,array这个键对应的值是一个JSONArray,也就是一个数组的形式
(5)解析json字符串实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/**
* 解析json字符串
* */
publicvoidtestGetValue(){
JSONObjectjObject=newJSONObject();
jObject.put("1","1");
jObject.put("2",2);
jObject.accumulate("1","1.11");
jObject.accumulate("2",false);
Animaldove=newAnimal("stupid
dove",2);
jObject.accumulate("2",dove);
jObject.element("3","3");
System.out.println(jObject);
//
根据key取对应的字符串
Stringvalue=jObject.getString("2");
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
copyright © 2008-2019 亿联网络 版权所有 备案号:粤ICP备14031511号-2
|