1.关于JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
JSON建构于两种结构:
1)“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
2)值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
值(value)可以是双引号括起来的字符串(string)、数值(number)、true
、false
、 null
、对象(object)或者数组(array)。这些结构可以嵌套。
字符串(string)与C或者Java的字符串非常相似,是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。
数值(number)也与C或者Java的数值非常相似,除去未曾使用的八进制与十六进制格式。除去一些编码细节。
空白可以加入到任何符号之间。
2.JSON-LIB简介
JSON是一个开源的JAVA项目,实现了JSON和JAVA Object之间的互转,也实现了JSON和XML之间的互转,本文将关注前者。
针对JSON的两种结构,JSON-LIB采用了两个类:
1)JSONObject,处理JSON对象
2)JSONArray,处理JSON数组
默认类型转化关系
JSON JAVA
string java.lang.String, java.lang.Character, char
number java.lang.Number, byte, short, int, long, float, double
true|false java.lang.Boolean, boolean
null null
array Object[]
object net.sf.ezmorph.bean.MorphDynaBean
JSON转化成JAVA Object
1)JSONObject.fromObject(XXX) & JSONArray.fromObject(XXX)
2)JSONObject.toBean(XXX) & JSONArray.toArray(XXX) & JSONArray.toList(XXX)
下面将介绍常用的几种自定义方式
1)指定JSON转化为JAVA Object的数据类型
JSONObject.toBean(XXX, class)
指定JSON转化为JAVA对象数组时的元素数据类型
JSONArray.toArray(XXX, class)
通过JsonConfig的rootClass属性指定
JsonConfig jCfg = new JsonConfig();
jCfg.setRootClass(Student.class);
JSONObject.toBean(XXX, jCfg);
JSONArray.toArray(XXX, jCfg)
2)值类型的处理
指定了rootClass之后属性类型可以进行自动处理,否则要进行指定
通过classMap参数指定
JSONObject.toBean(XXX, XXX, classMap)
通过JsonConfig的classMap属性指定
JsonConfig jCfg2 = new JsonConfig();
jCfg2.setRootClass(Map.class);
jCfg2.setClassMap(classMap);
JSONObject.toBean(XXX, jCfg);
但是假如rootClass中包含List属性,那该属性的元素数据类型仍需通过上述方式指定,否则为默认的MorphDynaBean
3)特殊属性类型的处理
通过JsonValueProcessor实现,例如Date属性转换成JSON
通过Morpher实现,例如JSON字符串转化为Date类型的属性
3.应用实例
Student.java
package com.siyuan.jsonlibtest.entity;
import java.util.Date;
import java.util.List;
public class Student {
private long studentNo;
private String name;
private boolean male;
private Date birthday;
private Student deskmate;
private List<Student> classmates;
public Student() {
}
public long getStudentNo() {
return studentNo;
}
public void setStudentNo(long studentNo) {
this.studentNo = studentNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isMale() {
return male;
}
public void setMale(boolean male) {
this.male = male;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Student getDeskmate() {
return deskmate;
}
public void setDeskmate(Student deskmate) {
this.deskmate = deskmate;
}
public List<Student> getClassmates() {
return classmates;
}
public void setClassmates(List<Student> classmates) {
this.classmates = classmates;
}
}
JSONLibTest.java
package com.siyuan.jsonlibtest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.DynaBean;
import com.siyuan.jsonlibtest.entity.Student;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;
import net.sf.json.util.JSONUtils;
public class JSONLibTest {
/**
* @param args
*/
public static void main(String[] args) {
String jsonStu0 = "{studentNo : 1, name : 'abc', male : true, birthday : '1987-01-01'}";
String jsonStu = "{studentNo : 2, name : 'bcd', male : true, birthday : null, deskmate : "
+ jsonStu0 + ", classmates : [" + jsonStu0 + "]}";
String jsonStus = "[ " + jsonStu0 + "," + jsonStu + "]";
System.out.println("默认数据类型转换----------------------------------------");
System.out.println("JSONObject---------------------------------");
JSONObject stuJSON = JSONObject.fromObject(jsonStu);
Object stuObj = JSONObject.toBean(stuJSON);
System.out.println(stuObj.getClass());
DynaBean stuObjBean = (DynaBean) stuObj;
System.out.println(stuObjBean.get("studentNo").getClass());
System.out.println(stuObjBean.get("name").getClass());
System.out.println(stuObjBean.get("male").getClass());
System.out.println(stuObjBean.get("birthday"));
System.out.println(stuObjBean.get("deskmate").getClass());
System.out.println(stuObjBean.get("classmates").getClass());
System.out.println("JSONArray----------------------------------");
JSONArray studsJson = JSONArray.fromObject(jsonStus);
System.out.println(JSONArray.toArray(studsJson).getClass());
System.out.println(JSONArray.toList(studsJson).getClass());
//必须在此处注册否则系统将提供一个默认的Morpher,导致后面注册的不生效
String[] dateFormats = new String[] { "yyyy-MM-dd" };
JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
System.out.println("自定义数据类型转换--------------------------------------");
System.out.println("JSONObject---------------------------------");
System.out.println(JSONObject.toBean(stuJSON, Student.class));
JsonConfig stuJCFG = new JsonConfig();
stuJCFG.setRootClass(Student.class);
stuObj = JSONObject.toBean(stuJSON, stuJCFG);
System.out.println(stuObj.getClass());
Student stu = (Student) stuObj;
System.out.println(stu.getStudentNo());
System.out.println(stu.getName());
System.out.println(stu.isMale());
System.out.println(stu.getBirthday());
System.out.println(stu.getDeskmate());
System.out.println(stu.getClassmates());
System.out.println("JSONArray----------------------------------");
System.out.println(JSONArray.toArray(studsJson, Student.class));
System.out.println(JSONArray.toList(studsJson, Student.class));
//此处注册将不生效
// String[] dateFormats = new String[] { "yyyy-MM-dd" };
// JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
System.out.println("值类型处理----------------------------------------------");
stuJCFG = new JsonConfig();
stuJCFG.setRootClass(Student.class);
Map classMap = new HashMap();
classMap.put("classmates", Student.class);
stuJCFG.setClassMap(classMap);
stu = (Student) JSONObject.toBean(stuJSON, stuJCFG);
System.out.println(stu.getClassmates());
System.out.println("特殊属性类型处理----------------------------------------------");
System.out.println("JAVA2JSON--------------------------------------");
stu = new Student();
stu.setBirthday(new Date());
System.out.println(JSONObject.fromObject(stu).toString());
stuJCFG = new JsonConfig();
stuJCFG.registerJsonValueProcessor("birthday", new JsonValueProcessor() {
private String dateFmt = "yyyy-MM-dd";
@Override
public Object processObjectValue(String key, Object value,
JsonConfig jsonConfig) {
return process(value);
}
@Override
public Object processArrayValue(Object value, JsonConfig jsonConfig) {
return process(value);
}
private Object process(Object value) {
if (value == null) {
return null;
} else if (value instanceof Date) {
return new SimpleDateFormat(dateFmt).format((Date) value);
} else {
return value;
}
}
});
System.out.println(JSONObject.fromObject(stu, stuJCFG).toString());
System.out.println("JSON2JAVA--------------------------------------");
JSONObject stuJSON1 = JSONObject.fromObject(jsonStu0);
Student stu1 = (Student) JSONObject.toBean(stuJSON1, Student.class);
System.out.println(stu1.getBirthday());
}
}
运行结果
默认数据类型转换----------------------------------------
JSONObject---------------------------------
class net.sf.ezmorph.bean.MorphDynaBean
class java.lang.Integer
class java.lang.String
class java.lang.Boolean
null
class net.sf.ezmorph.bean.MorphDynaBean
class java.util.ArrayList
JSONArray----------------------------------
class [Ljava.lang.Object;
class java.util.ArrayList
自定义数据类型转换--------------------------------------
JSONObject---------------------------------
com.siyuan.jsonlibtest.entity.Student@6b97fd
class com.siyuan.jsonlibtest.entity.Student
2
bcd
true
null
com.siyuan.jsonlibtest.entity.Student@1c78e57
[net.sf.ezmorph.bean.MorphDynaBean@1be2d65[
{birthday=1987-01-01, studentNo=1, name=abc, male=true}
]]
JSONArray----------------------------------
[Lcom.siyuan.jsonlibtest.entity.Student;@9664a1
[com.siyuan.jsonlibtest.entity.Student@1a8c4e7, com.siyuan.jsonlibtest.entity.Student@1172e08]
值类型处理----------------------------------------------
[com.siyuan.jsonlibtest.entity.Student@cf2c80]
特殊属性类型处理----------------------------------------------
JAVA2JSON--------------------------------------
{"birthday":{"date":30,"day":0,"hours":15,"minutes":43,"month":5,"seconds":59,"time":1372578239014,"timezoneOffset":-480,"year":113},"classmates":[],"deskmate":null,"male":false,"name":"","studentNo":0}
{"birthday":"2013-06-30","classmates":[],"deskmate":null,"male":false,"name":"","studentNo":0}
JSON2JAVA--------------------------------------
Thu Jan 01 00:00:00 CST 1987
4.参考资料
JSON详解 http://www.json.org/json-zh.html
JSON LIB官网:http://json-lib.sourceforge.net/