使用JSONObject 深度序列化和反序列化

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的文章,將在接下來的博文中陸續呈現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章