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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值