JSONObject 和JSONArray 是json-lib.jar裏面最常用的兩個類,分別可以對對象和數組(集合)進行序列化和反序列化,結構清晰命了,簡單易用,功能強大,效率比較高,使用至今一直較爲推崇,雖然尚有諸多功能尚未完全瞭解,姑且邊學邊記,以作歸納、沉澱。
首先看兩個類:
Student類:
public class Student {
private String name;
private String gerder;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGerder() {
return gerder;
}
public void setGerder(String gerder) {
this.gerder = gerder;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Classes類:
public class Classes {
private String clsNum;
private String claName;
private String way;
private List<Student> students;
private Student student;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String getClsNum() {
return clsNum;
}
public void setClsNum(String clsNum) {
this.clsNum = clsNum;
}
public String getClaName() {
return claName;
}
public void setClaName(String claName) {
this.claName = claName;
}
public String getWay() {
return way;
}
public void setWay(String way) {
this.way = way;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
值得注意的是:Classes類中,既包含Student對象,也包含List<Student> 這樣的集合,這是爲了讓我麼接下來的操作更有深度些:
測試類:MyTest
public class MyTest {
public static void main(String[] args) {
Student student = new Student();
student.setName("zxl");
student.setGerder("M");
student.setAddress("beijing");
Classes cs = new Classes();
cs.setClaName("計算機1");
cs.setClsNum("07060341");
cs.setWay("wentaoyuan1");
List<Student> list = new ArrayList<Student>();
list.add(student);
cs.setStudents(list);
cs.setStudent(student);}}
這時我們的cs對象已經封裝好了,接下來進行序列化:
System.out.println(JSONObject.fromObject(cs).toString());
結果:{"claName":"計算機1","clsNum":"07060341","student":{"address":"beijing","gerder":"M","name":"zxl"},"students":[{"address":"beijing","gerder":"M","name":"zxl"}],"way":"wentaoyuan1"}
看以看到序列化是深度沒有問題,所有的字段包括嵌套(姑且這麼叫)的對象的字段也都完善了,看以稱之爲“徹底的序列化”。
接下來看一下反序列化:
JSONObject jo = JSONObject.fromObject("{'clsNum':'123','claName':'計算機1','student':{'address':'guangzhou','gerder':'F','name':'zxl'},'students':[{'address':'shanghai','gerder':'M','name':'zxl'}],'way':'wentaoyuan1'}");
Classes cls = (Classes) JSONObject.toBean(jo, Classes.class);
System.out.println(cls.getClsNum() + "==" + cls.getStudent().getAddress());
結果:123==guangzhou
也沒有問題。
注:當嵌套的對象較多時,看以寫一個Class Map來註明反序列化的各個類路徑,如:
Map<String, Class<?>> clazz = new HashMap<String, Class<?>>();
clazz.put("student", Student.class);
clazz.put("students", Student.class);
可以使用toBean的重載方法設置clazz也可以通過jsonconfig的setClassMap(clazz);來設置如果我有這麼一個需求,在對象cs的基礎上我要把jo的數據封裝給它,這時候就要用到toBean的另一個重載方法:
Map<String, Class<?>> clazz = new HashMap<String, Class<?>>();
clazz.put("student", Student.class);
clazz.put("students", Student.class);
JSONObject jo = JSONObject.fromObject("{'clsNum':'123','claName':'計算機1','student':{'address':'guangzhou','gerder':'F','name':'zxl'},'students':[{'address':'shanghai','gerder':'M','name':'zxl'}],'way':'wentaoyuan1'}");
JsonConfig jc = new JsonConfig();
jc.setClassMap(clazz);
Classes cls = (Classes) JSONObject.toBean(jo, cs, jc);
這時候有個問題了,當jo中的屬性clsNum不存在的時候,會出現什麼問題呢?
實驗證明,當某個屬性不存在的時候,該屬性的值不被覆蓋,等於cs原有的值。
當jo中student中的屬性,address不存在的時候,會不會也是上面的那個情況呢?
JSONObject jo = JSONObject
.fromObject("{'clsNum':'123','claName':'計算機1','student':{'gerder':'F','name':'zxl'},'students':[{'address':'shanghai','gerder':'M','name':'zxl'}],'way':'wentaoyuan1'}");
JsonConfig jc = new JsonConfig();
jc.setClassMap(clazz);
Classes cls = (Classes) JSONObject.toBean(jo, cs, jc);
System.out.println(cls.getClsNum() + "==" + cls.getStudent().getAddress());
打印結果:
123==null
結論:深層次的對象如果不存在某個屬性,則會被覆蓋掉。
那麼能不能讓它跟一級屬性一樣,不進行覆蓋呢?我覺得應該是可以實現的,這個問題當然要着落在jsonConfig上,上面有很多設置,大多數我還沒有看明白,因此暫時不知道怎麼辦?但如果這個功能是由我來設計,我一定會設置這麼一個開關,默認覆蓋深層次的屬性,當然可以調整回來。
請各位網友給與賜教,如何來解決這個問題?
其他關於Json-lib的文章,將在接下來的博文中陸續呈現。