org.json源码分析及增强(⼀)——JSONObject对象与Java对
象相互转换
为什么是org.json
JSONObject.java: The JSONObject can parse text from a String or a JSONTokener to produce a map-like object. The object provides methods for manipulating its contents, and for producing a JSON compliant object serialization.
JSONArray.java: The JSONObject can parse text from a String or a JSONTokener to produce a vector-like object. The object provides methods for manipulating its contents, and for producing a JSON compliant array serialization.
JSONTokener.java: The JSONTokener breaks a text into a sequence of individual tokens. It can be constructed from a String, Reader, or InputStream.
JSONException.java: The JSONException is the standard exception type thrown by this package.
JSONPointer.java: Implementation of . Supports
JSON Pointers both in the form of string representation and URI fragment
representation.
JSONString.java: The JSONString interface requires a toJSONString method,allowing an object to provide its own serialization.
JSONStringer.java: The JSONStringer provides a convenient facility for building JSON strings.
JSONWriter.java: The JSONWriter provides a convenient facility for building JSON text through a writer.
CDL.java: CDL provides support for converting between JSON and comma delimited lists.
Cookie.java: Cookie provides support for converting between JSON and cookies.
CookieList.java: CookieList provides support for converting between JSON and cookie lists.
HTTP.java: HTTP provides support for converting between JSON and HTTP headers.
HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers.
XML.java: XML provides support for converting between JSON and XML.
JSONML.java: JSONML provides support for converting between JSONML and XML.
XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text.
JSONObject.java源码分析
JSONObject是⼀个核⼼类,它内部利⽤HashMap进⾏存储,实现了从⼀个字符串、Map对象、Java对象,JSONObject对象⾃⾝来构建⼀个key-value形式的JSON数据格式类型对象(这种数据格式与JavaScript的对象格式⾮常相似)。从⽽达到Map⼀样的操作,并可以输出为标准的JSON字符串。
在源码分析中我们主要讨论从字符串转换为JSONObject对象和从Java对象转换为JSONObject对象:
(1)字符串转换为JSONObject对象
public JSONObject(String source) throws JSONException {
this(new JSONTokener(source));
}
转换利⽤JSONTokener类,⾸先将字符串转换为可以将其按JSON数据格式拆解为⼀个⼀个循序的char对象的JSONTokener对象,之后遵循JSON数据格式的标准规则:
1. 以”{“开头;
2. 以”}”结尾;
3. key后⾯紧跟着”:”;
4. 属性对(key-value)之间使⽤”,”分割。
利⽤以下代码,按JSONTokener对象所拆解的每个char对象⼀种顺序循环直⾄出现JSON语法错误或到达尾部终⽌,最终完成对HashMap的填充:
public JSONObject(JSONTokener x) throws JSONException {
this();
char c;
String key;
if (x.nextClean() != '{') {
throw x.syntaxError("A JSONObject text must begin with '{'");
}
for (;;) {
c = x.nextClean();
switch (c) {
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
}
// The key is followed by ':'.
c = x.nextClean();
if (c != ':') {
throw x.syntaxError("Expected a ':' after a key");
}
this.putOnce(key, x.nextValue());
// Pairs are separated by ','.
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == '}') {
return;
}
x.back();
break;
case '}':
return;
default:
throw x.syntaxError("Expected a ',' or '}'");
}
}
}
这⾥需要注意的是,在进⾏key和value取值时,使⽤了JSONTokener类的nextValue()⽅法,此⽅法将通过字符对类型进⾏判断,⽬前⽀持Boolean, Double, Integer,JSONArray, JSONObject, Long, String, JSONObject.NULL类型,主要的逻辑代码参考如下:
switch (c) {
case '"':
case '\'':
String(c);
case '{':
this.back();
return new JSONObject(this);
case '[':
this.back();
return new JSONArray(this);
}
除去”外,\’对应⼀个String类型,{对应⼀个JSONObject类型,[对应⼀个JSONArray类型,对于”会继续判断,最终通过JSONObject.stringToValue()⽅法返回对应类型的Object对象。
(2)Java对象转换为JSONObject对象
public JSONObject(Object bean) {
this();
this.populateMap(bean);
}
object to转换的实际是⼀个JavaBean对象,实际⽅法为populateMap,可以理解为是⼀个对于JavaBean对象实现序列化的通⽤⽅法。我们可以关注populateMap的⼏个细节。
1. 通过getClassLoader()来判断处理的是否是⼀个纯系统(JRE)类或是⼀个基本类型,从JRS中我们可以看到这样⼀个描述:
Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader.
This method will return null in such implementations if this class was loaded by the bootstrap class loader.
If this object represents a primitive type or void, null is returned.
当启动⼀个JVM时,Bootstrap Classloader会加载java的核⼼类,也就是我们说的System Class,当你试图获取其类加载器时会返回⼀个null,因为Bootstrap Classloader并不是⼀个Java类,⽽是⼀个JVM的内部实现;另外,当获取基本类型的Classloader时也同样返回null。
2. 通过Modifier.Modifiers())判断是否为public⽅法,通过反射get⽅法获取对应的key值和value值,并利⽤wrap ⽅法对value值判断类型后进⾏分别处理,wrap⽅法代码如下:
public static Object wrap(Object object) {//核⼼⽅法:将⽬标对象包裹成⼀整个JSONObject中的value对象
try {
if (object == null) {
return NULL;
}
//对于基本数据类型,直接进⾏使⽤
if (object instanceof JSONObject || object instanceof JSONArray
|| NULL.equals(object) || object instanceof JSONString
|| object instanceof Byte || object instanceof Character
|| object instanceof Short || object instanceof Integer
|| object instanceof Long || object instanceof Boolean
|| object instanceof Float || object instanceof Double
|| object instanceof String || object instanceof BigInteger
|| object instanceof BigDecimal || object instanceof Enum) {
return object;
}
//对于集合类型将作为⼀个JSONArray
if (object instanceof Collection) {
Collection<?> coll = (Collection<?>) object;
return new JSONArray(coll);
}
//对于⼀个数组类型将作为⼀个JSONArray
if (Class().isArray()) {
return new JSONArray(object);
}
//对于⼀个Map类型
if (object instanceof Map) {
Map<?, ?> map = (Map<?, ?>) object;
return new JSONObject(map);
}
Package objectPackage = Class().getPackage();
String objectPackageName = objectPackage != null ? objectPackage
.getName() : "";
if (objectPackageName.startsWith("java.")
|| objectPackageName.startsWith("javax.")
|| Class().getClassLoader() == null) {
String();
}
return new JSONObject(object);
} catch (Exception exception) {
return null;
}
}
JSONObject对象与Java对象相互转换
org.json中的JSONObject类默认只⽀持将Java对象转换为JSONObject对象(这个可以从上⽂的源码分析中了解到),⽬前是不⽀持JSONObject对象到Java对象的转换的,因此,此章节将重点介绍我们如何来修改JSONObject类来增加JSONObject对象转换为Java对象的功能。
构建测试Java对象
需要构建⼀个相对复杂⼀点的测试对象,参考如下JavaBean对象代码:
public class Person {
String name = null;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Student extends Person{
String id = null;
String[] course = null;
int[] weightArray = null;
Map<String, Object> map = null;
ArrayList<Integer> scoreList = null;
JSONObject json = null;
Random rand = null;
Clothes clothes = null;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String[] getCourse() {
return course;
}
public void setCourse(String[] course) {
}
public int[] getWeightArray() {
return weightArray;
}
public void setWeightArray(int[] weightArray) { this.weightArray = weightArray;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) { this.map = map;
}
public ArrayList<Integer> getScoreList() {
return scoreList;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论