[Android開發] Json解析工具類,一個類搞定Json的解析
阿新 • • 發佈:2019-01-03
一、簡介
利用遞迴的方式反射解析到bean裡面
二、詳細程式碼
1、 Json格式
例如伺服器指定規定json格式為:
{
"code": "……" , // 返回代號,預留欄位,預設返回null
"type":"ERROR", // 返回型別,表示操作是成功或失敗
"desc":"……", // 返回描述,描述性文字,主要儲存用於彈窗顯示的文字
"action":"SHOW", //返回操作,該操作值提供給終端使用,用於決定當前收到返回後的操作
"data": "……" // 返回資料,根據請求上傳的引數,返回對應的資料,或返回null
}
對應的資料在data裡面,data裡面的key對應一個bean,例如一個列表資料:
{
"desc":"查詢成功",
"data":{
"diseaseList":[
{
"xmlName":"精神病評估",
"xmlId":"1066",
"category":"symptom"
},
{
"xmlName":"對學習困難和認知延遲的評估",
"xmlId ":"884",
"category":"symptom"
},
{
"xmlName":"疲乏的評估",
"xmlId":"571",
"category":"symptom"
},
{
"xmlName":"痴呆的評估",
"xmlId":"242",
"category":"symptom"
},
{
"xmlName":"非故意性體重減輕評估",
"xmlId":"548",
"category":"symptom"
}
]
},
"action":null,
"code":"",
"type":"SUCCESS"
}
2、定義資料Bean類
上面的list的bean定義為DiseaseList.java
public class DiseaseList {
/**
* xmlName : 分裂情感性障礙
* xmlId : 1199
* category : disease
*/
private String xmlName; //症狀名字
private String xmlId; //症狀名字
private String category; //分類的 英文名
private String letter = ""; //字母,轉為拼音後在這裡新增
public String getXmlName() {
return xmlName;
}
public void setXmlName(String xmlName) {
this.xmlName = xmlName;
}
public String getXmlId() {
return xmlId;
}
public void setXmlId(String xmlId) {
this.xmlId = xmlId;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getLetter() {
return letter;
}
public void setLetter(String letter) {
this.letter = letter;
}
}
3、定義根key的bean類
Response.java:
/**
* json返回的首key的內容類
*
*/
public class Response {
//下面四個是固定寫在第一層的
private String code;
private String type;
private String desc;
private String action;
//Object 可以存放list
private HashMap<String,Object> datas = new HashMap<String,Object>(); //存放物件(一般是list),根據String這個id來取
//存放data裡面的基本型別
private HashMap<String,Object> dataValue = new HashMap<>();
public Response() {
code = type = desc = action /*= version = token = applyAuthenticateId*/ = "";
}
public final static String TOKEN = "token";
public final static String VERSION = "version";
public final static String PORTRAIT = "portrait";
public final static String USERID = "userId";
public final static String APPLYAUTHENTICATEID = "applyAuthenticateId";
public final static String ISDOCTOR = "isDoctor";
public final static String ISEXPERT = "isExpert";
public final static String WAY = "way";
public final static String DOWNLOAD = "download";
/**
* 存值到hashmap裡面
* @param key
* @param value
*/
public void put(String key, Object value) {
datas.put(key, value);
}
/**
* 獲取key對應的物件
* @param key key
* @param <T> 返回的物件
* @return hashMap的key對應的值
*/
public <T> T get(String key){
if(datas.containsKey(key)){
return (T)datas.get(key);
}
return null;
}
/**
* 反射執行,新增到hashMap,data裡面的基本型別資料
* @param key
* @param value
*/
public void addDataValue(String key, Object value){
dataValue.put(key,value);
}
/**
* 獲取data裡面的基本型別資料
* @param key
* @param <T>
* @return
*/
public <T> T getDataValue(String key){
if(dataValue.containsKey(key)){
return (T)dataValue.get(key);
}
return null;
}
public String getCode() {
return code;
}
public void setCode(String code) {
if(null != code && !"".equals(code.trim()))
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
if(!TextUtils.isEmpty(desc))
this.desc = desc;
}
}
4、定義反射類列舉
json解析時候根據key在這裡獲取到對應的類例項
DATA.java:
/**
* json解析的時候的類
*/
public enum DATA {
//疾病列表
DISEASELIST("diseaseList",DiseaseList.class)
;
private final String mId;
private final Class cls;
public Class getClzss() {
return cls;
}
DATA(String id, Class clzss) {
mId = id;
cls = clzss;
}
/**
* 根據json的key獲取類
* @param id
* @return
*/
public static DATA fromId(String id) {
DATA[] values = values();
int cc = values.length;
for (int i = 0; i < cc; i++) {
if (values[i].mId.equals(id)) {
return values[i];
}
}
return null;
}
@Override
public String toString() {
return mId;
}
}
5、 Json解析工具類
對應的註釋已經寫到程式碼裡面了
JsonResolveUtils.java
/**
* json解析工具類
*/
public class JsonResolveUtils {
private static final String SET = "set";
private static final String PUT = "put";
/**
* 開始解析json 字串,解析為Response類bean形式
*
* @param response json字串
* @param cls Response類class
* @param <T> 泛型,這裡傳遞了Response
* @return
*/
public static <T> T parseJsonToResponse(String response, Class<T> cls) {
if (null != response) {
try {
// 構建JSONObject 例項
JSONObject json = new JSONObject(response);
// JSONObject 解析成具體Bean例項
T entity = toResponse(json, cls);
return entity;
} catch (JSONException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* JSONObject解析成Response Bean例項
*
* @param json json物件
* @param cls 轉換的物件,這裡是Response
* @param <T> 轉換的物件,這裡是Response
* @return 返回Response物件
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static <T> T toResponse(JSONObject json, Class<T> cls) throws IllegalAccessException, InstantiationException {
//宣告一個Response例項
T instance = null;
if (null != json) {
// 獲取根key
Iterator<String> iterator = json.keys();
//構建個例項Response Bean
instance = cls.newInstance();
//開始遍歷根 key
while (iterator.hasNext()) {
try {
String key = iterator.next(); //獲取key
Object value = json.get(key); //獲取key對應的值
//值不為空
if (null != value) {
if (!key.equals("data")) {
//不是data資料,直接為Response的Bean屬性賦值
setter(instance, key, value);
} else { // 解析data資料
if (value instanceof JSONObject) {
//data 資料是JSONObject 開始解析json物件資料
parseJsonBean((JSONObject) value, instance);
} else if (value instanceof JSONArray) {
//data 資料是JSONArray 開始解析json陣列資料
toBeanArray((JSONArray) value, instance);
} else {
//若都不是,直接為ResponseBean屬性賦值
setter(instance, key, value);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
} // while(~)
}
return instance;
}
/**
* 解析單個JSON資料
*
* @param json json
* @param instance Bean例項
* @param <T>
*/
public static <T> void parseJsonBean(JSONObject json, T instance) {
//json不為空
if (null != json) {
//獲取json的key iterator
Iterator<String> iterator = json.keys();
while (iterator.hasNext()) {
//獲取鍵值對
String key = iterator.next();
Object value = null;
try {
//獲取值
value = json.get(key);
//value不為空
if (null != value) {
// value 為json物件 則把json解析成具體的例項Bean
if (value instanceof JSONObject) {
// 獲取對應的例項Bean Class
DATA clzss = DATA.fromId(key);
//不為空
if (null != clzss) {
//把json解析成該例項Bean
Object entity = toBean((JSONObject) value, clzss.getClzss());
//把當前Bean類快取在上級Bean屬性裡
putter(instance, entity.getClass(), key, entity);
}
} else if (value instanceof JSONArray) { //value 為json 資料物件,則把jsonarray解析成ArrayList<Bean>
// 獲取對應的例項Bean Class
DATA clzss = DATA.fromId(key);
if (null != clzss) {
//把json解析成ArrayList<Bean>
Object entity = parseBeanArray((JSONArray) value, clzss.getClzss());
//把當前ArrayList<Bean>快取在上級Bean屬性裡
putter(instance, entity.getClass(), key, entity);
}
} else {
//都是不是,直接為上級Bean屬性賦值
if (instance instanceof Response) {
//dada下面的標準型別的值設定進Respone的dataString
setDataString(instance,key, value.toString());
} else {
putter(instance, value.getClass(), key, value);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
/**
* 設定Response的dataString
*
* @param obj
* @param key
* @param value
* @param <T>
*/
private static <T> void setDataString(Object obj, String key, String value) {
//值不為空
if (null == value)
return;
try {
//獲取addDataString方法,引數1 為方法名,2為型別
Method method = obj.getClass().getMethod("addDataValue", String.class, Object.class);
//呼叫set方法賦值
method.invoke(obj, key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 解析JSON成具體例項Bean
*
* @param json json資料
* @param cls 要解析成為的例項
* @param <T> 返回例項
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static <T> T toBean(JSONObject json, Class<T> cls) throws IllegalAccessException, InstantiationException {
//宣告例項引用
T instance = null;
//json不為空
if (null != json) {
//獲取json key 的迭代器;
Iterator<String> iterator = json.keys();
//構建例項Bean
instance = cls.newInstance();
//遍歷json key
while (iterator.hasNext()) {
//獲取鍵值對
String key = iterator.next();
Object value = null;
try {
value = json.get(key);
//value不為空
if (null != value) {
// value 為json物件 則把json解析成具體的例項Bean
if (value instanceof JSONObject) {
// 獲取對應的例項Bean Class
DATA clzss = DATA.fromId(key);
if (null != clzss) {
//把json解析成該例項Bean
Object entity = toBean((JSONObject) value, clzss.getClzss());
//把當前Bean類快取在上級Bean屬性裡
putter(instance, entity.getClass(), key, entity);
}
} else if (value instanceof JSONArray) { //value 為json陣列物件,則把jsonarray解析成ArrayList<Bean>
// 獲取對應的例項Bean Class
DATA clzss = DATA.fromId(key);
if (null != clzss) {
//把json解析成ArrayList<Bean>
Object entity = parseBeanArray((JSONArray) value, clzss.getClzss());
//把當前ArrayList<Bean>快取在上級Bean屬性裡
putter(instance, entity.getClass(), key, entity);
}
} else {
//都是不是,直接為上級Bean屬性賦值
setter(instance, key, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return instance;
}
/**
* 解析json裡面的json陣列,例如專家列表
*
* @param jsonarr
* @param cls
* @param <T>
* @return
*/
public static <T> ArrayList<Object> parseBeanArray(JSONArray jsonarr, Class<T> cls) {
//宣告集合List引用
ArrayList<Object> beanArray = null;
//宣告例項引用
T instance = null; // if area
if (null != jsonarr && jsonarr.length() > 0) {
beanArray = new ArrayList<Object>();
int count = jsonarr.length();
Object value = null;
for (int index = 0; index < count; index++) {
try {
value = jsonarr.get(index);
if (value instanceof String) {
beanArray.add(value);
continue;
} else {
//構造例項Bean
instance = cls.newInstance();
// value 為json物件 則把json解析成具體的例項Bean
if (value instanceof JSONObject) {
parseJsonBean((JSONObject) value, instance);
} else if (value instanceof JSONArray) {
//value 為json 陣列物件,則解析jsonarray
toBeanArray((JSONArray) value, instance);
}
//解析完成後將Bean新增到List
beanArray.add(instance);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return beanArray;
}
/**
* 解析data的key 的json陣列
*
* @param jsonarr json資料
* @param instance Response例項
* @param <T>
* @return
*/
public static <T> T toBeanArray(JSONArray jsonarr, T instance) {
if (null != jsonarr && jsonarr.length() > 0) {
int count = jsonarr.length();
Object value = null;
for (int index = 0; index < count; index++) {
try {
value = jsonarr.get(index);
if (value instanceof JSONObject) {
parseJsonBean((JSONObject) value, instance);
} else if (value instanceof JSONArray) {
toBeanArray((JSONArray) value, instance);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return instance;
}
/**
* 呼叫obj類的get引數menber方法
*
* @param obj
* @param member
* @param <T>
* @return
*/
public static <T> T getter(Object obj, String member) {
try {
Method method = obj.getClass().getMethod("get" + updateFirst(member));
return (T) method.invoke(obj);
} catch (Exception e) {
return null;
}
}
/**
* 反射的方法獲取
*
* @param obj
* @param member
* @param <T>
* @return
*/
public static <T> T getterIgnoreCase(Object obj, String member) {
try {
Method method = obj.getClass().getMethod("get" + member);
return (T) method.invoke(obj);
} catch (Exception e) {
return null;
}
}
/**
* 為obj例項的屬性賦值
*
* @param obj 目標例項
* @param clzss set方法形參型別
* @param value 屬性值
*/
public static void putter(Object obj, Class<?> clzss, Object... value) {
//值不為空
if (null == value)
return;
try {
//獲取key對應的set方法,引數1 為方法名,2為型別
Method method = obj.getClass().getMethod(SET + updateFirst((String) value[0]), clzss);
//呼叫set方法賦值
method.invoke(obj, value[1]);
} catch (Exception e) {
//若obj沒有對應的set方法
try {
//獲取obj的put方法
Method method = obj.getClass().getMethod(PUT, value[0].getClass(), Object.class);
//把屬性值put入map裡快取
method.invoke(obj, value);
//System.out.println(obj.getClass()+ "呼叫"+value[0].toString()+" "+((ArrayList)value[1]).size());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* 反射執行
*
* @param obj
* @param member
* @param value
*/
public static void setter(Object obj, String member, Object value) {
if (null == value)
return;
try {
Method method = obj.getClass().getMethod(SET + updateFirst(member), value.getClass());
method.invoke(obj, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 首字元大寫
*
* @param member
* @return
*/
public static String updateFirst(String member) {
String first = member.substring(0, 1).toUpperCase();
String suffex = member.substring(1, member.length());
return new StringBuilder().append(first).append(suffex).toString();
}
}
三、使用
例如第一個資料獲取到list資料
//解析為response
Response response = JsonResolveUtils.parseJsonToResponse(json,Response.class);
從response裡面獲取list資料
List<DiseaseList> list = new ArrayList<>();
//獲取完成開始解析為list bean
Response response = JsonResolveUtils.parseJsonToResponse(json,Response.class);
ArrayList cache = null;
cache = response.get(DATA.DISEASELIST.toString());
if(cache != null && !cache.isEmpty()){
//新增到list
list.addAll(cache);
Log.e("tpnet",list.size()+"個數據");
}else{
//獲取資料失敗操作
}
四、使用注意
解析的時候是根據返回的格式進行解析的,如果有數字型別的資料。在bean裡面應該寫完整幾種型別的數字,例如金額:
public class FinanceRecords {
private String sum; //金額
public String getSum() {
return sum;
}
//新增下面四種類型供json反射回調
public void setSum(String sum) {
this.sum = sum;
}
public void setSum(Integer sum) {
this.sum = sum+"";
}
public void setSum(Float sum) {
this.sum = sum+"";
}
public void setSum(Double sum) {
this.sum = sum+"";
}
}
下一篇文章有一個完整的demo。