遇到幾種Json類型,使用Gson經過自定義解析器解析一下幾種類型的返回數據。web
JSON示例
返回Json中data爲空json
{
"data": "",
"code": 1,
"message": "請求失敗" }
返回Json中data值爲nullide
{
"data": null,
"code": 1,
"message": "請求失敗" }
返回Json中data爲對象類型svg
{
"data": { "name": "秦川小將", "phone": "182******08" },
"code": 0,
"message": "請求成功" }
返回Json中的data爲集合類型ui
{
"data": [{ "name": "張三", "phone": "182******08" }, { "name": "李四", "phone": "182******08" }],
"code": 0,
"message": "請求成功" }
返回Json中的data的值爲字符串,解析時須要去除轉義字符拿到具體的對象this
{
"data": "{
\"id\":2981,\"title\":\"除夕活動啓動頁\",\"content\":\"\",\"url\":\"http://np.test.com/Activity/MonsterNian20180215\"}",
"code": 0,
"message": "請求成功"
}
返回Json中的data的值爲字符串,解析時須要去除轉義字符拿到具體的集合對象url
{
"data": "[{
\"id\":2981,\"title\":\"除夕活動啓動頁\",\"content\":\"\",\"url\":\"http://np.test.com/Activity/MonsterNian20180215\"},{
\"id\":2849,\"title\":\"默認啓動頁\",\"content\":\"\",\"url\":\"\"}]",
"code": 0,
"message": "請求成功"
}
定義基礎類
爲了防止重複寫除data值之外的屬性,這裏定義一個基礎類。spa
public class ResultData<T> {
public T data;
public int code;
public String message;
/** * 擴展字段 * 0:data爲對象 * 1:data爲集合 * 2:date爲空或者null字段 */
public int dataType;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getDataType() {
return dataType;
}
public void setDataType(int dataType) {
this.dataType = dataType;
}
@Override
public String toString() {
return "{" +
"data=" + data +
", code=" + code +
", message='" + message + '\'' +
", dataType=" + dataType +
'}';
}
}
自定義解析器
實現 JsonDeserializer 接口重寫 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 方法,這裏進行解析處理,針對特殊字段特殊處理。.net
public class JsonFormatParser implements JsonDeserializer<ResultData> {
private Class mClass;
public JsonFormatParser(Class tClass) {
this.mClass = tClass;
}
@Override
public ResultData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// 根據Json元素獲取Json對象。
JsonObject mJsonObject = json.getAsJsonObject();
ResultData mResult = new ResultData();
// 因爲Json是以鍵值對的形式存在的,此處根據鍵(data)獲取對應的Json字符串。
String mJson = mJsonObject.get("data").toString();
// 判斷是Array仍是Object類型。
if (mJsonObject.get("data").isJsonArray() && !mJsonObject.get("data").isJsonNull()) {
mResult.setData(fromJsonArray(mJson, mClass));
mResult.setDataType(1);
} else if (mJsonObject.get("data").isJsonObject() && !mJsonObject.get("data").isJsonNull()) {
mResult.setData(fromJsonObject(mJson, mClass));
mResult.setDataType(0);
} else if (mJsonObject.get("data").isJsonPrimitive() && !mJsonObject.get("data").isJsonNull()) {
// 服務端返回data的值爲"{}","[]",將對象或者集合以字符串的形式返回回來,先去除兩邊的雙引號,再去掉轉義字符。
String mNewJson = mJson.substring(1, mJson.length() - 1).replaceAll("\\\\", "");
// 根據處理好的Json字符串判斷是集合仍是對象,再進行解析。
if (mNewJson.startsWith("[") || mNewJson.endsWith("]")) {
mResult.setData(fromJsonArray(mNewJson, mClass));
mResult.setDataType(1);
} else if (mNewJson.startsWith("{") || mNewJson.endsWith("}")) {
mResult.setData(fromJsonObject(mNewJson, mClass));
mResult.setDataType(0);
} else {
mResult.setData(fromJsonObject(mResult.toString(), mClass));
mResult.setDataType(2);
}
} else if (mJsonObject.get("data").isJsonNull() || mJsonObject.get("data").getAsString().isEmpty()) {
mResult.setData(fromJsonObject(mResult.toString(), mClass));
mResult.setDataType(2);
}
// 根據鍵獲取返回的狀態碼。
mResult.setCode(mJsonObject.get("code").getAsInt());
// 根據鍵獲取返回的狀態信息。
mResult.setMessage(mJsonObject.get("message").getAsString());
return mResult;
}
/** * 用來解析對象 */
private <T> T fromJsonObject(String json, Class<T> type) {
return new Gson().fromJson(json, type);
}
/** * 用來解析集合 */
private <T> ArrayList<T> fromJsonArray(String json, Class<T> clazz) {
Type type = new TypeToken<ArrayList<JsonObject>>() {
}.getType();
ArrayList<JsonObject> jsonObjects = new Gson().fromJson(json, type);
ArrayList<T> arrayList = new ArrayList<>();
for (JsonObject jsonObject : jsonObjects) {
arrayList.add(new Gson().fromJson(jsonObject, clazz));
}
return arrayList;
}
}
Gson配置
public class FromJsonUtils {
public static ResultData fromJson(String json, Class clazz) {
return new GsonBuilder()
.registerTypeAdapter(ResultData.class, new JsonFormatParser(clazz))
.enableComplexMapKeySerialization()
.serializeNulls()
.create()
.fromJson(json, ResultData.class);
}
}
具體調用
public class JsonTest {
private static final String mJson1 = "{
\"data\": \"\", \"code\": 1, \"message\": \"請求失敗\"}";
private static final String mJson2 = "{
\"data\": null, \"code\": 1, \"message\": \"請求失敗\"}";
private static final String mJson3 = "{
\"data\": {
\"name\": \"秦川小將\", \"phone\": \"182******08\"}, \"code\": 0, \"message\": \"請求成功\"}";
private static final String mJson4 = "{
\"data\": [{
\"name\": \"張三\", \"phone\": \"182******08\"},{
\"name\": \"李四\", \"phone\": \"182******08\"}],\"code\": 0, \"message\": \"請求成功\"}";
private static final String mJson5 = "{
\"data\":\"{
\\\"id\\\":2981,\\\"title\\\":\\\"除夕活動啓動頁\\\",\\\"content\\\":\\\"\\\",\\\"url\\\":\\\"http://np.test.com/Activity/MonsterNian20180215\\\"}\",\"code\":0,\"message\":\"請求成功\"}";
private static final String mJson6 = "{
\"data\":\"[{
\\\"id\\\":2981,\\\"title\\\":\\\"除夕活動啓動頁\\\",\\\"content\\\":\\\"\\\",\\\"url\\\":\\\"http://np.test.com/Activity/MonsterNian20180215\\\"},{
\\\"id\\\":2849,\\\"title\\\":\\\"默認啓動頁\\\",\\\"content\\\":\\\"\\\",\\\"url\\\":\\\"\\\"}]\",\"code\":0,\"message\":\"請求成功\"}";
public static void main(String[] args) {
ResultData<DataBean> mData1 = FromJsonUtils.fromJson(mJson1, DataBean.class);
System.out.print("數據類型:" + mData1.getDataType() + "\t解析後取值:" + mData1.getData().getName() + "\n");
System.out.print("====================================" + "\n");
ResultData<DataBean> mData2 = FromJsonUtils.fromJson(mJson2, DataBean.class);
System.out.print("數據類型:" + mData2.getDataType() + "\t解析後取值:" + mData2.getData().getName() + "\n");
System.out.print("====================================" + "\n");
ResultData<DataBean> mData3 = FromJsonUtils.fromJson(mJson3, DataBean.class);
System.out.print("數據類型:" + mData3.getDataType() + "\t解析後取值:" + mData3.getData().getName() + "\n");
System.out.print("====================================" + "\n");
ResultData<List<DataBean>> mData4 = FromJsonUtils.fromJson(mJson4, DataBean.class);
for (DataBean mData : mData4.getData()) {
System.out.print("數據類型:" + mData4.getDataType() + "\t解析後取值:" + mData.getName() + "\n");
}
System.out.print("====================================" + "\n");
ResultData<ActivityBean> mData5 = FromJsonUtils.fromJson(mJson5, ActivityBean.class);
System.out.print("數據類型:" + mData5.getDataType() + "\t解析後取值:" + mData5.getData().getTitle() + "\n");
System.out.print("====================================" + "\n");
ResultData<List<ActivityBean>> mData6 = FromJsonUtils.fromJson(mJson6, ActivityBean.class);
for (ActivityBean mActivity : mData6.getData()) {
System.out.print("數據類型:" + mData6.getDataType() + "\t解析後取值:" + mActivity.getTitle() + "\n");
}
}
}
打印輸出: code
數據類型:2 解析後取值:null ====================================
數據類型:2 解析後取值:null ====================================
數據類型:0 解析後取值:秦川小將 ====================================
數據類型:1 解析後取值:張三
數據類型:1 解析後取值:李四 ====================================
數據類型:0 解析後取值:除夕活動啓動頁 ====================================
數據類型:1 解析後取值:除夕活動啓動頁
數據類型:1 解析後取值:默認啓動頁
示例數據實體類
public class DataBean {
public String name;
public String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
public class ActivityBean {
private int id;
private String title;
private String content;
private String url;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
本文分享 CSDN - 秦川小將。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。