Java算法JSONBean相互转化及JSON⽣成实体类
前⾔:之前解析JSON数据的时候使⽤的是GSON,相信⼤家已经⾮常熟悉,在封装开源控件的时候觉得GSON还是太重了⽽且别⼈在使⽤的时候不⼀定⽤这个解析框架,那就⾃⼰写⼀个解析的⼯具吧。
⼀、概述
将JSON封装到Bean对象,就是将JSON所对应的数据⼀⼀赋值到实例对象上,那么可以逆向过来,看该Bean对象有哪些字段,然后⽤字段的名称去JSON中去查值,再将查询到的赋值到该字段。
⼆、JSON语法
也⾏⼤家向我之前⼀样对于JSON的语法不太了解,知道客户端去访问后台提供的接⼝,后台返回给我JSON字符串,我写⼀个实体对象,然后使⽤⼯具(GSON、Jackson、Json-lib等)⼀⾏代码就封装到了对象上。既然我们要⾃⼰编写解析的话就要简单了解下JSON究竟是怎样定义的。
1. JSON 数据的书写格式
数据在名称/值对中
数据由逗号分隔
花括号保存对象
⽅括号保存数组
2. JSON的值
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在⽅括号中)
对象(在花括号中)
null
3. JSON 对象
JSON 对象在花括号中书写:
对象可以包含多个名称/值对:
{ "firstName":"Zhou" , "lastName":"Kevin" }
4. JSON 数组
JSON 数组在⽅括号中书写:
数组可包含多个对象:
{
"employees": [
{
"firstName": "Zhou", "lastName": "Kevin"
},
{
"firstName": "Li", "lastName": "Qian"
},
{
"firstName": "Peter", "lastName": "Jones"
}
]
}
三、反射的简单回顾
1. 根据类字节码获取实例
假设有⼀个类 T 以及它的字节码 clazz
T t = wInstance();
这样调⽤的是该类⽆参的构造函数,创建了实例对象。
上⾯的⽅式对于内部类就⽆计可施了,我们⼤家都知道创建内部类对象的时候需要外部类引⽤(指针),假设有这么⼀个类:
public class Outer {
public class Inner{
}
}
那么我们想要创建Inner的实例对象就要按照以下的⽅式:
Outer outer = new Outer();
Inner inner = w Inner();
当然在利⽤反射时候也需要有外部类的引⽤(指针),如下:
Outer outer = wInstance();
Constructor<?> constructor = DeclaredConstructors()[0];
constructor.setAccessible(true);
Inner inner = (Inner) wInstance(outer);
2. 根据类字节码获取所有字段
Field[] fields = c.getDeclaredFields();
3. 获取某⼀字段的类型名称
String name = Type().getName();
String类型字段类型名称:java.lang.String
int类型字段类型名称:int
Integer类型字段类型名称:java.lang.Integer
boolean类型字段类型名称:boolean
Boolean类型字段类型名称:java.lang.Boolean
float类型字段类型名称:float
Float类型字段类型名称:java.lang.Float
double类型字段类型名称:double
Double类型字段类型名称:java.lang.Double
List类型字段类型名称:java.util.List
ArrayList类型字段类型名称:java.util.ArrayList
其他的为类类型字段名称:如 com.kevin.jsontool.bean.TestBean2$LoopData为内部类
4.设置某⼀字段的值
假设有如下类:
public class Person{
public String name;
public int age;
}
Pserson p = wInstance();
Field[] fields = DeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Class<?> type = Type();
String typeName = Name();
if(typeName.equalsIgnoreCase("java.lang.String")) {
field.set(p, "Kevin");
} else if(typeName.equalsIgnoreCase("int")) {
field.set(p, 25);
}
}
四、JSONTool toBean编写
在前⽂提到过,是反射实例对象的字段然后去JSONObject查对应的值,当然也可以在字段的头上加上⾃⼰的注解这样可以字段的名称可以和JSONObject 中名称(键)不严格⼀致,这⾥不去做了。
/**
* 将JSON字符串封装到对象
*
* @param jsonStr 待封装的JSON字符串
* @param clazz 待封装的实例字节码
* @return T: 封装JSON数据的对象
* @version 1.0
*/
public static <T> T toBean(String jsonStr, Class<T> clazz) {
try {
JSONObject job = new JSONObject(jsonStr);
return parseObject(job, clazz, null);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* JSONObject 封装到对象实例
*
* @param job 待封装的JSONObject
* @param c 待封装的实例对象class
* @param v 待封装实例的外部类实例对象</br>只有内部类存在,外部类时传递null
* @return T:封装数据的实例对象
* @version 1.0
* @date 2015-10-9
* @Author zhou.wenkai
*/
@SuppressWarnings("unchecked")
private static <T, V> T parseObject(JSONObject job, Class<T> c, V v) {
T t = null;
try {
if(null == v) {
t = c.newInstance();
} else {
Constructor<?> constructor = c.getDeclaredConstructors()[0]; constructor.setAccessible(true);
t = (T) wInstance(v);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.e(SimpleName(),
"(a public constructor with no arguments)");
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Class<?> type = Type();
String name = Name();
// if the object don`t has a mapping for name, then continue if(!job.has(name)) continue;
String typeName = Name();
if(typeName.equals("java.lang.String")) {
try {
String value = String(name);
if (value != null && value.equals("null")) {
value = "";
}
field.set(t, value);
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
try {
field.set(t, "");
} catch (Exception e1) {
if(DEBUG)
e1.printStackTrace();
}
}
} else if(typeName.equals("int") ||
typeName.equals("java.lang.Integer")) {
try {
field.set(t, Int(name));
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
} else if(typeName.equals("boolean") ||
typeName.equals("java.lang.Boolean")) {
try {
field.set(t, Boolean(name));
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
} else if(typeName.equals("float") ||
typeName.equals("java.lang.Float")) {
try {
field.set(t, Float.String(name)));
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
} else if(typeName.equals("double") ||
typeName.equals("java.lang.Double")) {
try {
field.set(t, Double(name));
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
json值的类型有哪些}
} else if(typeName.equals("long") ||
typeName.equals("java.lang.Long")) {
try {
field.set(t, Long(name));
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
} else if(typeName.equals("java.util.List") ||
typeName.equals("java.util.ArrayList")){
try {
Object obj = (name);
Type genericType = GenericType();
String className = String().replace("<", "") .Name(), "").replace(">", "");
Class<?> clazz = Class.forName(className);
if(obj instanceof JSONArray) {
ArrayList<?> objList = parseArray((JSONArray)obj, clazz, t); field.set(t, objList);
}
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
} else {
try {
Object obj = (name);
Class<?> clazz = Class.forName(typeName);
if(obj instanceof JSONObject) {
Object parseJson = parseObject((JSONObject)obj, clazz, t); field.set(t, parseJson);
}
} catch (Exception e) {
if(DEBUG)
e.printStackTrace();
}
}
}
return t;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论