CreaAndroid【1】用注解和反射实现Json自动化解析

来源:互联网 发布:水利bim软件 编辑:程序博客网 时间:2022/05/28 06:52

今天才写第一篇真正的博客,实在是拖了太长的时间,废话少说,先上一个自己写的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. */@Jsonablepublic 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. */@Jsonablepublic 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());    }

自己运行一下,看看是不是你想要的效果呢?

0 0
原创粉丝点击