通過反射解析json,無需依賴三方

package com.example.jsontools;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

/**
 * @author wly
 * @date 2016-07-22
 */
public class JsonUtil {

	/**
	 * 解析字符串 
	 */
	public static String getString(String jsonStr, String key){
		if(isEmpty(jsonStr) || isEmpty(key))
			return null;
		try {
			JSONObject obj = new JSONObject(jsonStr);
			String content = obj.optString(key);
			if(isEmpty(content))
				//統一將所有的空值狀態返回爲""
				return "";
			return content;
		} catch (JSONException e) {
			Log.e("JsonUtil", e.getMessage());
		}
		return null;
	}
	
	/**
	 * 無數據或解析異常時返回int最小值
	 */
	public static int getInt(String jsonStr, String key){
		if(isEmpty(jsonStr) || isEmpty(key))
			return Integer.MIN_VALUE;
		try {
			JSONObject obj = new JSONObject(jsonStr);
			int content = obj.optInt(key);
			return content;
		} catch (JSONException e) {
			return Integer.MIN_VALUE;
		}
	}
	
	/**
	 * 無數據或解析異常時返回long最小值
	 */
	public static long getLong(String jsonStr, String key){
		if(isEmpty(jsonStr) || isEmpty(key))
			return Long.MIN_VALUE;
		try{
			JSONObject obj = new JSONObject(jsonStr);
			long l = obj.optLong(key);
			return l;
		} catch (JSONException e){
			return Long.MIN_VALUE;
		}
	}
	
	/**
	 * 無數據或解析異常時返回Double最小值
	 */
	public static double getDouble(String jsonStr, String key){
		if(isEmpty(jsonStr) || isEmpty(key))
			return Double.MIN_VALUE;
		try{
			JSONObject obj = new JSONObject(jsonStr);
			double d = obj.optDouble(key);
			return d;
		} catch (JSONException e){
			return Double.MIN_VALUE;
		}
	}
	
	/**
	 * 將json轉換爲List<Bean>
	 */
	public static <T> List<T> json2BeanList(String jsonStr, Class<T> clazz){
		if(isEmpty(jsonStr))
			return null;
		try{
			List<T> beans = new ArrayList<T>();
			JSONArray arr = new JSONArray(jsonStr);
			for(int i = 0; i < arr.length(); i++)
				beans.add(json2Bean(arr.optJSONObject(i).toString(), clazz));
			return beans;
		} catch (Exception e) {
			Log.e("JsonUtil", e.getMessage());
		}
		return null;
	}
	
	/**
	 * 將json轉換爲Bean
	 */
	public static <T> T json2Bean(String jsonStr, Class<T> clazz){
		if(isEmpty(jsonStr))
			return null;
		try {
			JSONObject obj = new JSONObject(jsonStr);
			T bean = json2BeanByAttr(clazz, obj);
			return bean;
		} catch (InstantiationException e) {
			Log.e("JsonUtil", e.getMessage());
		} catch (IllegalAccessException e) {
			// 說明訪問到了私有的屬性,表示該javaBean是private的
			try {
				JSONObject obj = new JSONObject(jsonStr);
				T bean = json2BeanByMethod(clazz, obj);
				return bean;
			} catch (JSONException e1) {
				Log.e("JsonUtil", e1.getMessage());
			} catch (InstantiationException e1) {
				Log.e("JsonUtil", e1.getMessage());
			} catch (IllegalAccessException e1) {
				Log.e("JsonUtil", e1.getMessage());
			} catch (IllegalArgumentException e1) {
				Log.e("JsonUtil", e1.getMessage());
			} catch (InvocationTargetException e1) {
				Log.e("JsonUtil", e1.getMessage());
			}
		} catch (JSONException e) {
			Log.e("JsonUtil", e.getMessage());
		}
		return null;
	}
	
	/**
	 * 當javaBean屬性爲private修飾時通過set方法設置屬性值
	 */
	private static <T> T json2BeanByMethod(Class<T> clazz, JSONObject obj) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		T bean = clazz.newInstance();
		Method[] methods = clazz.getMethods();
		Field[] fds = clazz.getDeclaredFields();
		for(Field fd : fds){
			List<T> datas = null;
			if(beanContainsCollection(fd)) {
				JSONArray arr = obj.optJSONArray(fd.getName());
				for (int j = 0; j < methods.length; j++) {
					if(methods[j].getName().equalsIgnoreCase("get" + fd.getName()))
					{
						Type fc = fd.getGenericType();
						if(fc == null) continue;  
			            if(fc instanceof ParameterizedType){  
			            	// 如果是泛型參數的類型   
			                ParameterizedType pt = (ParameterizedType) fc;  
			                Class<T> genericClazz = (Class<T>) pt.getActualTypeArguments()[0]; // 得到泛型裏的class類型對象。  
			                datas = json2BeanList(arr.toString(), genericClazz);;
			            }   
					}
				}
			}
			for (int i = 0; i < methods.length; i++) {
				if(methods[i].getName().equalsIgnoreCase("set" + fd.getName()))//拼接方法名
					if(datas != null && datas.size() > 0)
						methods[i].invoke(bean, datas);//執行方法
					else	
						methods[i].invoke(bean, obj.opt(fd.getName()));//執行方法
			}
		}
		return bean;
	}
	
	/**
	 * 當javaBean屬性爲public修飾時直接設置屬性值
	 */
	private static <T> T json2BeanByAttr(Class<T> clazz, JSONObject obj) throws InstantiationException, IllegalAccessException{
		T bean = clazz.newInstance();
		Field[] fds = clazz.getDeclaredFields();
		for(Field fd : fds)
            fd.set(bean, obj.opt(fd.getName()));//設置屬性
		return bean;
	}
	
	/**
	 * 集合對象轉json
	 */
	public static <T> String beanList2Json(/*Class<T> bean,*/ List<T> infos){
		if(infos == null || infos.size() == 0)
			return null;
		StringBuffer buffer = new StringBuffer();
		buffer.append("[");
		for (int i = 0; i < infos.size(); i++) 
			buffer.append(bean2Json((Class<T>) infos.get(i).getClass(), infos.get(i)) + ((i == infos.size() - 1) ? "" : "," ));
		return buffer.append("]").toString();
	}
	
	/**
	 * Map<T, T>集合嵌套轉換爲json
	 */
	public static <T> String beanMap2Json(Map<T, T> maps){
		if(maps.size() == 0 || maps == null)
			return null;
		StringBuffer buffer = new StringBuffer();
//		buffer.apped("{");
		Set<T> keys = maps.keySet();
		for(T key : keys){
			if(maps.get(key).getClass().toString().contains("Map"))
				return "\"" + key + "\":" + beanMap2Json((Map<T, T>)maps.get(key));
			 else if(maps.get(key).getClass().toString().contains("List"))
				return "\"" + key + "\":" + beanList2Json((List<T>)maps.get(key));
			String bean2Json = bean2Json((Class<T>)maps.get(key).getClass(), maps.get(key));
			buffer.append("\"" + key + "\":[{").append(bean2Json.substring(1, bean2Json.length() - 1)).append("}],");
		}
		return buffer.substring(0, buffer.length() - 1);
	}

	/**
	 * Map<T, List<T>>集合嵌套轉換爲json
	 */
	public static <T> String beanListMap2Json(/*Class<T> bean, */Map<T, List<T>> maps){
		if(maps.size() == 0 || maps == null)
			return null;
		StringBuffer buffer = new StringBuffer();
		buffer.append("{");
		Set<T> keys = maps.keySet();
		for(T key : keys)
			buffer.append("\"" + key + "\":").append(beanList2Json(/*bean, */maps.get(key))).append(",");
		return buffer.substring(0, buffer.length() - 1) + "}";
	}
	
	
	/**
	 * 對象轉json
	 */
	public static <T> String bean2Json(Class<T> clazz, T info){
		try {
			String json = bean2JsonByAttr(clazz, info);
			return json;
		} catch (IllegalAccessException e) {
			// 說明訪問到了私有的屬性,表示該javaBean是private的
			try {
				String json = bean2JsonByMethod(/*clazz, */info);
				return json;
			} catch (Exception e1) {
				Log.e("JsonUtil", e1.getMessage());
			}
		}
		return null;
	}
	
	private static <T> String bean2JsonByAttr(Class<T> clazz, T info) throws IllegalAccessException{
		StringBuffer buffer = new StringBuffer();
		Field[] fds = clazz.getDeclaredFields();
		buffer.append("{");
		for(Field fd : fds){
			if(beanContainsCollection(/*clazz, */fd/*, info*/)){
				String jsonBean = beanType(/*clazz,*/ fd, info);
				buffer.append(jsonBean + ",");
				continue;
			}
			String name = fd.getName();
			Object value = fd.get(info);
			try{
				if(fd.getType().newInstance() instanceof String)
					buffer.append("\"" + name + "\":\"" + value + "\",");
				else
					buffer.append("\"" + name + "\":" + value + ",");
			} catch (InstantiationException e) {
				buffer.append("\"" + name + "\":" + value + ",");
			}
		}
		return buffer.substring(0, buffer.length() - 1) + "}";
	}
	
	private static <T> String bean2JsonByMethod(/*Class<T> clazz, */T info) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		StringBuffer buffer = new StringBuffer();
		Method[] methods = info.getClass().getMethods();
		Field[] fds = info.getClass().getDeclaredFields();
		buffer.append("{");
		for(Field fd : fds){
			if(beanContainsCollection(/*clazz, */fd/*, info*/)){
				String jsonBean = beanType(/*clazz,*/ fd, info);
				buffer.append(jsonBean + ",");
				continue;
			}
			for (int i = 0; i < methods.length; i++) {
				if(methods[i].getName().equalsIgnoreCase("get" + fd.getName())){
					Object value = methods[i].invoke(info);//執行方法
					String name = fd.getName();
					try{
						if(fd.getType().newInstance() instanceof String)
							buffer.append("\"" + name + "\":\"" + value + "\",");
						else
							buffer.append("\"" + name + "\":" + value + ",");
					} catch (InstantiationException e) {
						buffer.append("\"" + name + "\":" + value + ",");
					}
				}
			}
		}
		return buffer.substring(0, buffer.length() - 1) + "}";
	}
	
	/**
	 * 對象中如果包含有集合<對象>的處理方法
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	private static <T> String beanType(/*Class<T> clazz, */Field fd, T info){
		try {
			Object instance = fd.getType().newInstance();
		} catch (Exception e) {
			// 判斷該屬性是否是集合
			if(e.getMessage().contains("Map"))
				try {
					return beanMap2Json(/*clazz, */(Map<T, T>)fd.get(info));
				} catch (IllegalAccessException e1) {
					// 被private 修飾,調用get方法獲取參數
					return beanTypeByMethod(/*clazz, */fd, info, "map");
				} catch (IllegalArgumentException e1) {
					Log.e("JsonUtil", e1.getMessage());
				}
			if(e.getMessage().contains("List"))
				try {
					return beanList2Json(/*clazz, */(List<T>)fd.get(info));
				} catch (IllegalAccessException e1) {
					// 被private 修飾,調用get方法獲取參數
					return beanTypeByMethod(/*clazz, */fd, info, "list");
				} catch (IllegalArgumentException e1) {
					Log.e("JsonUtil", e1.getMessage());
				}
		}
//		// 判斷屬性爲哪種集合
//		if(instance instanceof Map) 
//			return beanListMap2Json(clazz, (Map<T, List<T>>)fd.get(info));
//		if(instance instanceof List)
//			return beanList2Json(clazz, (List<T>)fd.get(info));
		return null;
	}

	private static <T> String beanTypeByMethod(/*Class<T> clazz, */Field fd, T info, String type) {
		Method[] methods = info.getClass().getMethods();
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().equalsIgnoreCase("get" + fd.getName())){
				try {
					Object value = methods[i].invoke(info);
					if(type.equals("list"))
						return "\"" + fd.getName() + "\":" + beanList2Json(/*clazz, */(List<T>)value);
					else
						return beanMap2Json(/*clazz, */(Map<T, T>)value);
				} catch (IllegalAccessException e2) {
					Log.e("JsonUtil", e2.getMessage());
				} catch (IllegalArgumentException e2) {
					Log.e("JsonUtil", e2.getMessage());
				} catch (InvocationTargetException e2) {
					Log.e("JsonUtil", e2.getMessage());
				}
			}
		}
		return null;
	}
	
	/**
	 * 判斷對象中是否包含集合
	 */
	private static <T> boolean beanContainsCollection(/*Class<T> clazz, */Field fd/*, T info*/){
		try {
			Object instance = fd.getType().newInstance();
			// 判斷該屬性是否是集合
//			if(instance instanceof  Collection || instance instanceof Map)
//				return true;
		} catch (Exception e) {
			// 判斷該屬性是否是集合
			if(e.getMessage().contains("Map") || e.getMessage().contains("List"))
				return true;
		}
		return false;
	}
	
	/**
	 * 驗證非空
	 */
	private static boolean isEmpty(String str){
		if(str == null || "".equals(str) || "null".equals(str))
			return true;
		return false;
	}
}
相對於上一篇博客,這裏的方法更爲全面一些,新增功能:將Map<T, T>  Map<T , List<T>>轉換爲Json字符串,以及解析json時解析到對象中的List<Bean>的解析,如果有什麼問題,請及時指正,歡迎留言
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章