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/