使用json-lib進行Java和JSON之間的轉換
1. json-lib是一個java類庫,提供將Java對象,包括beans, maps, collections, java arrays and XML等轉換成JSON,或者反向轉換的功能。
2. json-lib 主頁 : http://json-lib.sourceforge.net/
3.執行環境
需要以下類庫支持
- jakarta commons-lang 2.5
- jakarta commons-beanutils 1.8.0
- jakarta commons-collections 3.2.1
- jakarta commons-logging 1.1.1
- ezmorph 1.0.6
這里通過JUnit-Case例子給出代碼示例
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.sf.ezmorph.Morpher;
import net.sf.ezmorph.MorpherRegistry;
import net.sf.ezmorph.bean.BeanMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.util.JSONUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.junit.Test;
public class JsonLibTest {
/*
* 普通類型、List、Collection等都是用JSONArray解析
*
* Map、自定義類型是用JSONObject解析
* 可以將Map理解成一個對象,里面的key/value對可以理解成對象的屬性/屬性值
* 即{key1:value1,key2,value2......}
*
* 1.JSONObject是一個name:values集合,通過它的get(key)方法取得的是key后對應的value部分(字符串)
* 通過它的getJSONObject(key)可以取到一個JSONObject,--> 轉換成map,
* 通過它的getJSONArray(key) 可以取到一個JSONArray ,
*
*
*/
//一般數組轉換成JSON
@Test
public void testArrayToJSON(){
boolean[] boolArray = new boolean[]{true,false,true};
JSONArray jsonArray = JSONArray.fromObject( boolArray );
System.out.println( jsonArray );
// prints [true,false,true]
}
//Collection對象轉換成JSON
@Test
public void testListToJSON(){
List list = new ArrayList();
list.add( "first" );
list.add( "second" );
JSONArray jsonArray = JSONArray.fromObject( list );
System.out.println( jsonArray );
// prints ["first","second"]
}
//字符串json轉換成json, 根據情況是用JSONArray或JSONObject
@Test
public void testJsonStrToJSON(){
JSONArray jsonArray = JSONArray.fromObject( "['json','is','easy']" );
System.out.println( jsonArray );
// prints ["json","is","easy"]
}
//Map轉換成json, 是用jsonObject
@Test
public void testMapToJSON(){
Map map = new HashMap();
map.put( "name", "json" );
map.put( "bool", Boolean.TRUE );
map.put( "int", new Integer(1) );
map.put( "arr", new String[]{"a","b"} );
map.put( "func", "function(i){ return this.arr[i]; }" );
JSONObject jsonObject = JSONObject.fromObject( map );
System.out.println( jsonObject );
}
//復合類型bean轉成成json
@Test
public void testBeadToJSON(){
MyBean bean = new MyBean();
bean.setId("001");
bean.setName("銀行卡");
bean.setDate(new Date());
List cardNum = new ArrayList();
cardNum.add("農行");
cardNum.add("工行");
cardNum.add("建行");
cardNum.add(new Person("test"));
bean.setCardNum(cardNum);
JSONObject jsonObject = JSONObject.fromObject(bean);
System.out.println(jsonObject);
}
//普通類型的json轉換成對象
@Test
public void testJSONToObject() throws Exception{
String json = "{name=\"json\",bool:true,int:1,double:2.2,func:function(a){ return a; },array:[1,2]}";
JSONObject jsonObject = JSONObject.fromObject( json );
System.out.println(jsonObject);
Object bean = JSONObject.toBean( jsonObject );
assertEquals( jsonObject.get( "name" ), PropertyUtils.getProperty( bean, "name" ) );
assertEquals( jsonObject.get( "bool" ), PropertyUtils.getProperty( bean, "bool" ) );
assertEquals( jsonObject.get( "int" ), PropertyUtils.getProperty( bean, "int" ) );
assertEquals( jsonObject.get( "double" ), PropertyUtils.getProperty( bean, "double" ) );
assertEquals( jsonObject.get( "func" ), PropertyUtils.getProperty( bean, "func" ) );
System.out.println(PropertyUtils.getProperty(bean, "name"));
System.out.println(PropertyUtils.getProperty(bean, "bool"));
System.out.println(PropertyUtils.getProperty(bean, "int"));
System.out.println(PropertyUtils.getProperty(bean, "double"));
System.out.println(PropertyUtils.getProperty(bean, "func"));
System.out.println(PropertyUtils.getProperty(bean, "array"));
List arrayList = (List)JSONArray.toCollection(jsonObject.getJSONArray("array"));
for(Object object : arrayList){
System.out.println(object);
}
}
//將json解析成復合類型對象, 包含List
@Test
public void testJSONToBeanHavaList(){
String json = "{list:[{name:'test1'},{name:'test2'}],map:[{test1:{name:'test1'}},{test2:{name:'test2'}}]}";
// String json = "{list:[{name:'test1'},{name:'test2'}]}";
Map classMap = new HashMap();
classMap.put("list", Person.class);
MyBeanWithPerson diyBean = (MyBeanWithPerson)JSONObject.toBean(JSONObject.fromObject(json),MyBeanWithPerson.class , classMap);
System.out.println(diyBean);
List list = diyBean.getList();
for(Object o : list){
if(o instanceof Person){
Person p = (Person)o;
System.out.println(p.getName());
}
}
}
//將json解析成復合類型對象, 包含Map
@Test
public void testJSONToBeanHavaMap(){
//把Map看成一個對象
String json = "{list:[{name:'test1'},{name:'test2'}],map:{test1:{name:'test1'},test2:{name:'test2'}}}";
Map classMap = new HashMap();
classMap.put("list", Person.class);
classMap.put("map", Map.class);
//使用暗示,直接將json解析為指定自定義對象,其中List完全解析,Map沒有完全解析
MyBeanWithPerson diyBean = (MyBeanWithPerson)JSONObject.toBean(JSONObject.fromObject(json),MyBeanWithPerson.class , classMap);
System.out.println(diyBean);
System.out.println("do the list release");
List<Person> list = diyBean.getList();
for(Person o : list){
Person p = (Person)o;
System.out.println(p.getName());
}
System.out.println("do the map release");
//先往注冊器中注冊變換器,需要用到ezmorph包中的類
MorpherRegistry morpherRegistry = JSONUtils.getMorpherRegistry();
Morpher dynaMorpher = new BeanMorpher( Person.class, morpherRegistry);
morpherRegistry.registerMorpher( dynaMorpher );
Map map = diyBean.getMap();
/*這里的map沒進行類型暗示,故按默認的,里面存的為net.sf.ezmorph.bean.MorphDynaBean類型的對象*/
System.out.println(map);
List<Person> output = new ArrayList();
for( Iterator i = map.values().iterator(); i.hasNext(); ){
//使用注冊器對指定DynaBean進行對象變換
output.add( (Person)morpherRegistry.morph( Person.class, i.next() ) );
}
for(Person p : output){
System.out.println(p.getName());
}
}
JSON字符串和java對象的互轉【json-lib】
在開發過程中,經常需要和別的系統交換數據,數據交換的格式有XML、JSON等,JSON作為一個輕量級的數據格式比xml效率要高,XML需要很多的標簽,這無疑占據了網絡流量,JSON在這方面則做的很好,下面先看下JSON的格式,
JSON可以有兩種格式,一種是對象格式的,另一種是數組對象,
{"name":"JSON","address":"北京市西城區","age":25}//JSON的對象格式的字符串
[{"name":"JSON","address":"北京市西城區","age":25}]//數據對象格式
從上面的兩種格式可以看出對象格式和數組對象格式唯一的不同則是在對象格式的基礎上加上了[],再來看具體的結構,可以看出都是以鍵值對的形式出現的,中間以英文狀態下的逗號(,)分隔。
在前端和后端進行數據傳輸的時候這種格式也是很受歡迎的,后端返回json格式的字符串,前台使用js中的JSON.parse()方法把JSON字符串解析為json對象,然后進行遍歷,供前端使用。
下面進入正題,介紹在JAVA中JSON和java對象之間的互轉。
要想實現JSON和java對象之間的互轉,需要借助第三方jar包,這里使用json-lib這個jar包,下載地址為:https://sourceforge.net/projects/json-lib/,json-lib需要commons-beanutils-1.8.0.jar、commons-collections-3.2.1.jar、commons-lang-2.5.jar、commons-logging-1.1.1.jar、ezmorph-1.0.6.jar五個包的支持,可以自行從網上下載,這里不再貼出下載地址。
json-lib提供了幾個類可以完成此功能,例,JSONObject、JSONArray。從類的名字上可以看出JSONObject轉化的應該是對象格式的,而JSONArray轉化的則應該是數組對象(即,帶[]形式)的。
一、java普通對象和json字符串的互轉
java對象--》》字符串
java普通對象指的是java中的一個java bean,即一個實體類,如,
package com.cn.study.day3;
public class Student {
//姓名
private String name;
//年齡
private String age;
//住址
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", address="
+ address + "]";
}
}
上面是我的一個普通的java實體類,看json-lib如何把它轉化為字符串形式,
public static void convertObject() {
Student stu=new Student();
stu.setName("JSON");
stu.setAge("23");
stu.setAddress("北京市西城區");
//1、使用JSONObject
JSONObject json = JSONObject.fromObject(stu);
//2、使用JSONArray
JSONArray array=JSONArray.fromObject(stu);
String strJson=json.toString();
String strArray=array.toString();
System.out.println("strJson:"+strJson);
System.out.println("strArray:"+strArray);
}
我定義了一個Student的實體類,然后分別使用了JSONObject和JSONArray兩種方式轉化為JSON字符串,下面看打印的結果,
strJson:{"address":"北京市西城區","age":"23","name":"JSON"}
strArray:[{"address":"北京市西城區","age":"23","name":"JSON"}]
從結果中可以看出兩種方法都可以把java對象轉化為JSON字符串,只是轉化后的結構不同。
JSON字符串--》》java對象
上面說明了如何把java對象轉化為JSON字符串,下面看如何把JSON字符串格式轉化為java對象,
首先需要定義兩種不同格式的字符串,需要使用\對雙引號進行轉義,
public static void jsonStrToJava(){
//定義兩種不同格式的字符串
String objectStr="{\"name\":\"JSON\",\"age\":\"24\",\"address\":\"北京市西城區\"}";
String arrayStr="[{\"name\":\"JSON\",\"age\":\"24\",\"address\":\"北京市西城區\"}]";
//1、使用JSONObject
JSONObject jsonObject=JSONObject.fromObject(objectStr);
Student stu=(Student)JSONObject.toBean(jsonObject, Student.class);
//2、使用JSONArray
JSONArray jsonArray=JSONArray.fromObject(arrayStr);
//獲得jsonArray的第一個元素
Object o=jsonArray.get(0);
JSONObject jsonObject2=JSONObject.fromObject(o);
Student stu2=(Student)JSONObject.toBean(jsonObject2, Student.class);
System.out.println("stu:"+stu);
System.out.println("stu2:"+stu2);
}
打印結果為:
stu:Student [name=JSON, age=24, address=北京市西城區] stu2:Student [name=JSON, age=24, address=北京市西城區]
從上面的代碼中可以看出,使用JSONObject可以輕松的把JSON格式的字符串轉化為java對象,但是使用JSONArray就沒那么容易了,因為它有“[]”符號,所以我們這里在獲得了JSONArray的對象之后,取其第一個元素即我們需要的一個student的變形,然后使用JSONObject輕松獲得。
二、list和json字符串的互轉
list--》》json字符串
public static void listToJSON(){
Student stu=new Student();
stu.setName("JSON");
stu.setAge("23");
stu.setAddress("北京市海淀區");
List<Student> lists=new ArrayList<Student>();
lists.add(stu);
//1、使用JSONObject
//JSONObject listObject=JSONObject.fromObject(lists);
//2、使用JSONArray
JSONArray listArray=JSONArray.fromObject(lists);
//System.out.println("listObject:"+listObject.toString());
System.out.println("listArray:"+listArray.toString());
}
我把使用JSONObject的方式給注掉了,我們先看注釋之前的結果,
Exception in thread "main" net.sf.json.JSONException: 'object' is an array. Use JSONArray instead
告訴我說有一個異常,通過查看源碼發現,在使用fromObject方法的時候會先進行參數類型的判斷,這里就告訴我們,傳入的參數是一個array類型,因為使用的ArrayList,再來看,注釋之后的結果,
listArray:[{"address":"北京市海淀區","age":"23","name":"JSON"}]
這樣結果是正常的。
json字符串--》》list
從上面的例子可以看出list的對象只能轉化為數組對象的格式,那么我們看下面的字符串到list的轉化,
public static void jsonToList(){
String arrayStr="[{\"name\":\"JSON\",\"age\":\"24\",\"address\":\"北京市西城區\"}]";
//轉化為list
List<Student> list2=(List<Student>)JSONArray.toList(JSONArray.fromObject(arrayStr), Student.class);
for (Student stu : list2) {
System.out.println(stu);
}
//轉化為數組
Student[] ss =(Student[])JSONArray.toArray(JSONArray.fromObject(arrayStr),Student.class);
for (Student student : ss) {
System.out.println(student);
}
}
打印結果,
Student [name=JSON, age=24, address=北京市西城區] Student [name=JSON, age=24, address=北京市西城區]
由於字符串的格式為帶有“[]”的格式,所以這里選擇JSONArray這個對象,它有toArray、toList方法可供使用,前者轉化為java中的數組,或者轉化為java中的list,由於這里有實體類進行對應,所以在使用時指定了泛型的類型(Student.class),這樣就可以得到轉化后的對象。
三、map和json字符串的互轉
map--》》json字符串
public static void mapToJSON(){
Student stu=new Student();
stu.setName("JSON");
stu.setAge("23");
stu.setAddress("中國上海");
Map<String,Student> map=new HashMap<String,Student>();
map.put("first", stu);
//1、JSONObject
JSONObject mapObject=JSONObject.fromObject(map);
System.out.println("mapObject"+mapObject.toString());
//2、JSONArray
JSONArray mapArray=JSONArray.fromObject(map);
System.out.println("mapArray:"+mapArray.toString());
}
打印結果,
mapObject{"first":{"address":"中國上海","age":"23","name":"JSON"}}
mapArray:[{"first":{"address":"中國上海","age":"23","name":"JSON"}}]
上面打印了兩種形式。
json字符串--》》map
JSON字符串不能直接轉化為map對象,要想取得map中的鍵對應的值需要別的方式,
public static void jsonToMap(){
String strObject="{\"first\":{\"address\":\"中國上海\",\"age\":\"23\",\"name\":\"JSON\"}}";
//JSONObject
JSONObject jsonObject=JSONObject.fromObject(strObject);
Map map=new HashMap();
map.put("first", Student.class);
//使用了toBean方法,需要三個參數
MyBean my=(MyBean)JSONObject.toBean(jsonObject, MyBean.class, map);
System.out.println(my.getFirst());
}
打印結果,
Student [name=JSON, age=23, address=中國上海]
下面是MyBean的代碼,
package com.cn.study.day4;
import java.util.Map;
import com.cn.study.day3.Student;
public class MyBean {
private Student first;
public Student getFirst() {
return first;
}
public void setFirst(Student first) {
this.first = first;
}
}
JoahYau
我在好好努力,你也不要停下前進的步伐。——給未來的自己
使用JSONObject生成和解析json
1. json數據類型
| 類型 | 描述 |
|---|---|
| Number | 數字型 |
| String | 字符串型 |
| Boolean | 布爾型 |
| Array | 數組 |
| Object | 對象 |
| null | 空值 |
(1)json中不區分整數、小數等類型,而統一使用Number來存儲數字。
(2)Array表示數組,以中括號"[]"括起來,元素之間以逗號分隔,元素可以為任意類型。
(3)Object表示對象,類似於C語言中的結構體,以花括號"{}"括起來,其元素要求為鍵值對,key必須為String類型的,而value則可為任意類型。key和value之間以":"表示映射關系,元素之間也是以逗號分隔。
2. 構建json
在eclipse中使用JSONObject需要引用org.json包,推薦通過maven引用,如果不會使用maven,搭建maven項目可參考這篇文章《使用Eclipse構建Maven項目 (step-by-step)》,引用json則參考這篇文章《maven引入json各種版本》。
溫馨提示:我在構建maven項目的時候屢屢創建失敗,在網上查了很久還是搞不定,后來科學上網就搞定了,如果你也創建失敗,可以嘗試一下。
如果是在Android Studio中,則可以直接使用。
2.1 直接構建
JSONObject obj = new JSONObject(); obj.put(key, value);
直接構建即直接實例化一個JSONObject對象,而后調用其put()方法,將數據寫入。put()方法的第一個參數為key值,必須為String類型,第二個參數為value,可以為boolean、double、int、long、Object、Map以及Collection等。當然,double以及int等類型只是在Java中,寫入到json中時,統一都會以Number類型存儲。
范例:
import org.json.JSONObject; public class JSONObjectSample { public static void main(String[] args) { createJson(); } private static void createJson() { JSONObject obj = new JSONObject(); obj.put("name", "John"); obj.put("sex", "male"); obj.put("age", 22); obj.put("is_student", true); obj.put("hobbies", new String[] {"hiking", "swimming"}); //調用toString()方法可直接將其內容打印出來 System.out.println(obj.toString()); } }
輸出結果為:
{"hobbies":["hiking","swimming"],"sex":"male","name":"John","is_student":true,"age":22}
這里可以看到,為了壓縮大小以便於更高效地傳輸,json把所有空格、換行符等空白符全部去掉了。如果想要直觀點看其內容,可以用一些在線的json解析器看,例如:http://www.jsoneditoronline.org/
2.2 使用HashMap構建
使用HashMap構建json,實際上即先創建好一個HashMap對象並且將數據打包進去,而后在創建JSONObject時將其作為一個參數傳進去。
范例:
public class JSONObjectSample { public static void main(String[] args) { createJsonByMap(); } private static void createJsonByMap() { Map<String, Object> data = new HashMap<String, Object>(); data.put("name", "John"); data.put("sex", "male"); data.put("age", 22); data.put("is_student", true); data.put("hobbies", new String[] {"hiking", "swimming"}); JSONObject obj = new JSONObject(data); System.out.println(obj.toString()); } }
2.3 使用JavaBean構建
相較於前兩種方法,實際開發中應用JavaBean構建json的情況更為常見,因為這樣代碼的重用率更高。
范例:
JavaBean:
public class PersonInfo { private String name; private String sex; private int age; private boolean isStudent; private String[] hobbies; public void setName(String name) { this.name = name; } public void setSex(String sex) { this.sex = sex; } public void setAge(int age) { this.age = age; } public void setStudent(boolean isStudent) { this.isStudent = isStudent; } public void setHobbies(String[] hobbies) { this.hobbies = hobbies; } //getter不能少 public String getName() { return name; } public String getSex() { return sex; } public int getAge() { return age; } public boolean isStudent() { return isStudent; } public String[] getHobbies() { return hobbies; } }
main:
import org.json.JSONObject; public class JSONObjectSample { public static void main(String[] args) { createJsonByJavaBean(); } private static void createJsonByJavaBean() { PersonInfo info = new PersonInfo(); info.setName("John"); info.setSex("male"); info.setAge(22); info.setStudent(true); info.setHobbies(new String[] {"hiking", "swimming"}); JSONObject obj = new JSONObject(info); System.out.println(obj); } }
需要注意一點,JavaBean一定要有getter方法,否則會無法訪問存儲的數據。
3. 解析json
解析json主要是基本類型如Number、boolean等,與數組Array。
基本類型的解析直接調用JSONObject對象的getXxx(key)方法,如果獲取字符串則getString(key),布爾值則getBoolean(key),以此類推。
數組的解析稍微麻煩一點,需要通過JSONObject對象的getJSONArray(key)方法獲取到一個JSONArray對象,再調用JSONArray對象的get(i)方法獲取數組元素,i為索引值。
范例:
首先在工程目錄"src/main/java"下創建一個json文件,用於解析。
demo.json:
{
"hobbies": [ "hiking", "swimming" ], "sex": "male", "name": "John", "is_student": true, "age": 22 }
在pom.xml中加入對commons-io的依賴,以便於使用FileUtils進行文件訪問:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.studying</groupId> <artifactId>myjson</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>myjson</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20160810</version> </dependency> <!--加入對commons-io的依賴--> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> </dependencies> </project>
主類:
import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.json.JSONArray; import org.json.JSONObject; public class JSONObjectSample { public static void main(String[] args) throws IOException { File file = new File("src/main/java/demo.json"); String content = FileUtils.readFileToString(file); //對基本類型的解析 JSONObject obj = new JSONObject(content); System.out.println("name:" + obj.getString("name")); System.out.println("sex:" + obj.getString("sex")); System.out.println("age" + obj.getInt("age")); System.out.println("is_student" + obj.getBoolean("is_student")); //對數組的解析 JSONArray hobbies = obj.getJSONArray("hobbies"); System.out.println("hobbies:"); for (int i = 0; i < hobbies.length(); i++) { String s = (String) hobbies.get(i); System.out.println(s); } } }

