今天才写第一篇真正的博客,实在是拖了太长的时间,废话少说,先上一个自己写的Json解析类吧,使用注解和反射写的,类似Gson,但是肯定没那么完善,满足一般需求尚可。自己写而不用Gson的原因就是因为Gson封装度太高用起来不好自由控制。
废话少说,上代码
package uu.com.jsondemo.json;
import org.json.JSONArray;
import org.json.JSONObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
public class JsonIn {
public <T> T fromJson(JSONObject jsonObject, Class<T> jsonableClass) {
return (T) readObject(jsonObject, jsonableClass);
}
public <T> void fromJson(JSONArray jsonArray, List<T> container) {
if (container != null) {
container.addAll((Collection<? extends T>) readCollection(jsonArray, container.getClass()));
}
}
private Object readClass(JSONObject jsonObject, Class<?> jsonableClass, Object outObject) {
if (jsonableClass.isAnnotationPresent(Jsonable.class)) {
try {
if (outObject == null) {
outObject = jsonableClass.newInstance();
}
for(Class<?> superClass = jsonableClass.getSuperclass(); superClass.equals(Object.class) == false; superClass = superClass.getSuperclass()) {
readClass(jsonObject, superClass, outObject);
}
Field[] fields = jsonableClass.getDeclaredFields();
for (Field field : fields) {
readField(jsonObject, outObject, field);
}
return outObject;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
return null;
}
private void readField(JSONObject jsonObject, Object outObject, Field field) throws IllegalAccessException {
if (checkRule(field)) {
if (field.isAnnotationPresent(Jsonable.JsonKey.class)) {
Jsonable.JsonKey jsonKey = field.getAnnotation(Jsonable.JsonKey.class);
if (jsonKey == null) {
return;
}
field.setAccessible(true);
Class<?> fieldClass = field.getType();
if (fieldClass.isPrimitive()) {
Object value = readPrimitiveField(fieldClass, jsonObject, jsonKey.name());
if (value != null) {
field.set(outObject, value);
}
} else {
if (fieldClass.equals(String.class)) {
field.set(outObject, JsonHelper.getStringValue(jsonObject, jsonKey.name(), null));
} else if (Iterable.class.isAssignableFrom(fieldClass)) {
JSONArray jsonArray = JsonHelper.getJsonArray(jsonObject, jsonKey.name(), null);
if (jsonArray != null) {
Object value = readCollection(jsonArray, fieldClass);
if (value != null) {
field.set(outObject, value);
}
}
} else if (fieldClass.isArray()) {
JSONArray jsonArray = JsonHelper.getJsonArray(jsonObject, jsonKey.name(), null);
if (jsonArray != null) {
Object value = readArray(jsonArray, fieldClass);
if (value != null) {
field.set(outObject, value);
}
}
} else {
JSONObject fieldObject = JsonHelper.getJsonObject(jsonObject, jsonKey.name(), null);
if (fieldObject != null) {
Object value = readClass(fieldObject, fieldClass, null);
if (value != null) {
field.set(outObject, value);
}
}
}
}
}
}
}
private Object readPrimitiveField(Class<?> fieldClass, JSONObject jsonObject, String key) {
if (fieldClass.equals(int.class)) {
return JsonHelper.getIntValue(jsonObject, key, 0);
} else if (fieldClass.equals(byte.class)) {
return JsonHelper.getIntValue(jsonObject, key, 0);
} else if (fieldClass.equals(char.class)) {
return JsonHelper.getIntValue(jsonObject, key, 0);
} else if (fieldClass.equals(short.class)) {
return JsonHelper.getIntValue(jsonObject, key, 0);
} else if (fieldClass.equals(float.class)) {
return (float) JsonHelper.getDoubleValue(jsonObject, key, 0);
} else if (fieldClass.equals(double.class)) {
return JsonHelper.getDoubleValue(jsonObject, key, 0);
} else if (fieldClass.equals(long.class)) {
return JsonHelper.getLongValue(jsonObject, key, 0);
} else if (fieldClass.equals(boolean.class)) {
return JsonHelper.getBooleanValue(jsonObject, key, false);
}
return null;
}
private <T extends Object> Collection<T> readCollection(JSONArray jsonArray, Class<?> fieldClass) {
int componentCount = jsonArray.length();
Collection<T> collection = null;
if (fieldClass.equals(List.class) || fieldClass.equals(ArrayList.class)) {
collection = new ArrayList<T>(componentCount);
} else if (fieldClass.equals(LinkedList.class)) {
collection = new LinkedList<T>();
}
if (collection != null) {
for (int i = 0; i < componentCount; i++) {
Object elementObject = JsonHelper.get(jsonArray, i, null);
if (elementObject != null) {
Object valueObject = readObject(elementObject, fieldClass);
if (valueObject != null) {
collection.add((T) valueObject);
}
}
}
}
return collection;
}
private Object readArray(JSONArray jsonArray, Class<?> fieldClass) {
int componentCount = jsonArray.length();
Class<?> componentType = fieldClass.getComponentType();
Object arrayObject = Array.newInstance(componentType, componentCount);
for (int i = 0; i < componentCount; i++) {
Object elementObject = JsonHelper.get(jsonArray, i, null);
if (elementObject != null) {
Object valueObject = readObject(elementObject, fieldClass);
if (valueObject != null) {
Array.set(arrayObject, i, valueObject);
}
}
}
return arrayObject;
}
private Object readObject(Object object, Class<?> fieldClass) {
if (object instanceof JSONArray) {
if (Iterable.class.isAssignableFrom(fieldClass)) {
return readCollection((JSONArray) object, fieldClass);
} else if (fieldClass.isArray()) {
return readArray((JSONArray) object, fieldClass);
}
} else if (object instanceof JSONObject) {
return readClass((JSONObject) object, fieldClass, null);
}
return object;
}
private boolean checkRule(Field field) {
boolean isValidRule = true;
if (field.isAnnotationPresent(Jsonable.JsonRule.class)) {
Jsonable.JsonRule jsonRule = field.getAnnotation(Jsonable.JsonRule.class);
if (jsonRule != null) {
if (jsonRule.fromJson() == false) {
isValidRule = false;
}
}
}
return isValidRule;
}
}
package uu.com.jsondemo.json;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
public class JsonOut {
public JSONObject toJson(Object object) {
return (JSONObject) writeObject(object);
}
public JSONArray toJsonArray(Iterable<?> collection) {
return writeIterable(collection);
}
public <T> JSONArray toJsonArray(T[] objects) {
return writeArray(objects);
}
private Object writeObject(Object object) {
Class<?> objectClass = object.getClass();
if (objectClass.isPrimitive() || objectClass.equals(String.class)) {
return object;
} else {
JSONObject jsonObject = new JSONObject();
for(Class<?> superClass = objectClass.getSuperclass(); superClass.equals(Object.class) == false; superClass = superClass.getSuperclass()) {
writeClass(object, superClass, jsonObject);
}
writeClass(object, objectClass, jsonObject);
return jsonObject;
}
}
private void writeClass(Object object, Class<?> objectClass,
JSONObject jsonObject) {
if (objectClass.isAnnotationPresent(Jsonable.class)) {
Jsonable jsonable = objectClass.getAnnotation(Jsonable.class);
if (jsonable != null) {
Field[] fields = objectClass.getDeclaredFields();
if (fields != null) {
for (Field field : fields) {
writeField(object, field, jsonObject);
}
}
}
}
}
private void writeField(Object object, Field field, JSONObject jsonObject) {
if (checkRule(field)) {
try {
if (field.isAnnotationPresent(Jsonable.JsonKey.class)) {
Jsonable.JsonKey jsonKey = field.getAnnotation(Jsonable.JsonKey.class);
if (jsonKey == null) {
return;
}
field.setAccessible(true);
String key = jsonKey.name();
Class<?> fieldTypeClass = field.getType();
if (fieldTypeClass.isPrimitive()) {
jsonObject.put(key, field.get(object));
} else {
Object fieldObject = field.get(object);
if (fieldObject != null) {
if (Iterable.class.isAssignableFrom(fieldTypeClass)) {
jsonObject.put(key, writeIterable((Iterable<?>) fieldObject));
} else if (fieldTypeClass.isArray()) {
jsonObject.put(key, writeArray(fieldObject));
} else {
jsonObject.put(key, writeObject(fieldObject));
}
}
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private JSONArray writeIterable(Iterable<?> it) {
JSONArray json = new JSONArray();
for (Object object : it) {
json.put(writeObject(object));
}
return json;
}
private JSONArray writeArray(Object array) {
JSONArray json = new JSONArray();
int arrayLength = Array.getLength(array);
Class<?> componentClass = array.getClass().getComponentType();
for (int i = 0; i < arrayLength; i++) {
if (componentClass.isPrimitive()) {
json.put(Array.get(array, i));
} else {
json.put(writeObject(Array.get(array, i)));
}
}
return json;
}
private boolean checkRule(Field field) {
boolean isValidRule = true;
if (field.isAnnotationPresent(Jsonable.JsonRule.class)) {
Jsonable.JsonRule jsonRule = field.getAnnotation(Jsonable.JsonRule.class);
if (jsonRule != null) {
if (jsonRule.toJson() == false) {
isValidRule = false;
}
}
}
return isValidRule;
}
}
package uu.com.jsondemo.json;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Jsonable {
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonKey {
public String name();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonRule {
public boolean toJson();
public boolean fromJson();
}
}
package uu.com.jsondemo.json;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class JsonHelper {
public static JSONObject asJsonObject(String json) {
try {
return (JSONObject) new JSONTokener(json).nextValue();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static JSONArray asJsonArray(String json) {
try {
return (JSONArray) new JSONTokener(json).nextValue();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getStringValue(String json, String key, String defaultValue) {
return JsonHelper.getStringValue(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static int getIntValue(String json, String key, int defaultValue) {
return JsonHelper.getIntValue(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static boolean getBooleanValue(String json, String key, boolean defaultValue) {
return JsonHelper.getBooleanValue(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static double getDoubleValue(String json, String key, double defaultValue) {
return JsonHelper.getDoubleValue(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static long getLongValue(String json, String key, long defaultValue) {
return JsonHelper.getLongValue(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static Object getValue(String json, String key, Object defaultValue) {
return JsonHelper.getValue(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static JSONObject getJsonObject(String json, String key, JSONObject defaultValue) {
return JsonHelper.getJsonObject(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static JSONArray getJsonArray(String json, String key, JSONArray defaultValue) {
return JsonHelper.getJsonArray(JsonHelper.asJsonObject(json), key, defaultValue);
}
public static String getStringValue(JSONObject jsonObject, String key, String defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getString(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static int getIntValue(JSONObject jsonObject, String key, int defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getInt(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static boolean getBooleanValue(JSONObject jsonObject, String key, boolean defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getBoolean(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static double getDoubleValue(JSONObject jsonObject, String key, double defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getDouble(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static long getLongValue(JSONObject jsonObject, String key, long defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getLong(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static Object getValue(JSONObject jsonObject, String key, Object defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.get(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static JSONObject getJsonObject(JSONObject jsonObject, String key, JSONObject defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getJSONObject(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static JSONArray getJsonArray(JSONObject jsonObject, String key, JSONArray defaultValue) {
if (JsonHelper.hasKey(jsonObject, key)) {
try {
return jsonObject.getJSONArray(key);
} catch (JSONException e) {
e.printStackTrace();
}
}
return defaultValue;
}
public static JSONObject getJsonObject(JSONArray jsonArray, int index, JSONObject defaultValue) {
try {
return jsonArray.getJSONObject(index);
} catch (Exception e) {
e.printStackTrace();
}
return defaultValue;
}
public static Object get(JSONArray jsonArray, int index, Object defaultValue) {
try {
return jsonArray.get(index);
} catch (Exception e) {
e.printStackTrace();
}
return defaultValue;
}
public static boolean hasKey(JSONObject jsonObject, String key) {
if (jsonObject != null && key != null && !"".equals(key)) {
return jsonObject.has(key) && !jsonObject.isNull(key);
}
return false;
}
}
下面我们来测试一下,先写两个测试类
package uu.com.jsondemo.test;
import java.util.List;
import uu.com.jsondemo.json.Jsonable;
/**
* Created by yanhaifeng on 2015/9/8.
*/
@Jsonable
public class TestBeanA {
@Jsonable.JsonKey(name="id")
private int id;
@Jsonable.JsonKey(name="name")
private String name;
@Jsonable.JsonKey(name="array")
private float[] array;
@Jsonable.JsonKey(name="list")
private List<String> list;
@Jsonable.JsonKey(name="child_bean")
private TestBeanB childBean;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setArray(float[] array) {
this.array = array;
}
public void setList(List<String> list) {
this.list = list;
}
public void setChildBean(TestBeanB childBean) {
this.childBean = childBean;
}
}
package uu.com.jsondemo.test;
import uu.com.aarimportdemo.json.Jsonable;
/**
* Created by yanhaifeng on 2015/9/8.
*/
@Jsonable
public class TestBeanB extends TestBeanA {
@Jsonable.JsonKey(name="child_name")
private String childname;
public void setChildname(String childname) {
this.childname = childname;
}
}
准备工作做好,开始测试
private void doTest() {
float[] array = new float[] { 1.1f, 2.2f, 3.3f };
List<String> list = new ArrayList<>();
list.add("hahaha");
list.add("hehehe");
TestBeanB childBean = new TestBeanB();
childBean.setChildname("this is a child");
childBean.setId(2);
TestBeanA bean = new TestBeanA();
bean.setId(1);
bean.setName("this is a bean");
bean.setArray(array);
bean.setList(list);
bean.setChildBean(childBean);
JSONObject jsonObject = new JsonOut().toJson(bean);
Log.e("json_test", jsonObject.toString());
TestBeanA outBean = new JsonIn().fromJson(jsonObject, TestBeanA.class);
Log.e("json_test", new JsonOut().toJson(outBean).toString());
}
自己运行一下,看看是不是你想要的效果呢?