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;
}
}
public class Classes {
private String clsNum;
private String claName;
private String way;
private List 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 getStudents() {
return students;
}
public void setStudents(List students) {
this.students = students;
}
}
测试类: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 list = new ArrayList();
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());
也没有问题。
注:当嵌套的对象较多时,看以写一个Class Map来注明反序列化的各个类路径,如:
Map> clazz = new HashMap>();
clazz.put("student", Student.class);
clazz.put("students", Student.class);
可以使用toBean的重载方法设置clazz也可以通过jsonconfig的setClassMap(clazz);来设置
如果我有这么一个需求,在对象cs的基础上我要把jo的数据封装给它,这时候就要用到toBean的另一个重载方法:
Map> clazz = new HashMap>();
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);
实验证明,当某个属性不存在的时候,该属性的值不被覆盖,等于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的文章,将在接下来的博文中陆续呈现。