天天看點

解析一個數組JsonArray下有多種資料類型JsonObject的Json

先看一下下面的Json,怎麼用Gson解析呢?上來就是數組,數組中的類型還不是同一種。

[
    {
        "list": [
            {
                "imageUrl": "http://p0.meituan.net/w.h/movie/fe0d4da87d70ba2b91e10ac98e0bf5ef1365131.png",
                "overallRating": 9.1,
                "chineseName": "芳華",
                "genre": "劇情,愛情,戰争",
                "datePublished": "2017-12-15大陸上映",
                "englishName": "Youth"
            },
            {
                "imageUrl": "http://p0.meituan.net/w.h/movie/28eb582e261f29d2402fb215a3203768833576.jpg",
                "overallRating": 0,
                "chineseName": "芳華",
                "genre": "電視劇,劇情",
                "datePublished": "",
                "englishName": ""
            },
            {
                "imageUrl": "http://p1.meituan.net/w.h/mmdb/2dcb93e68932a45d6da67d8c4134643d22897.jpg",
                "overallRating": 0,
                "chineseName": "芳華虛度",
                "genre": "劇情",
                "datePublished": ""
            }
        ],
        "searchType": 0
    },
    {
        "followerNum": 18,
        "imageUrl": "http://p0.meituan.net/w.h/movie/161d15747aad52767599c6938008603e35220.jpg",
        "chineseName": "葉芳華",
        "searchType": 1,
        "represent": "《紅番區》 《狂野三千響》 《誓死追緝令》",
        "englishName": "Françoise Yip"
    },
    {
        "list": [
            {
                "name": "屬于他們的芳華",
                "viewNum": 4,
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=985259",
                "reviewNum": 0
            },
            {
                "name": "芳華——影評",
                "viewNum": 6,
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=985150",
                "reviewNum": 0
            },
            {
                "name": "《畢業旅行笑翻天》荷爾蒙激蕩的芳華時代,闡述懵懂的青春",
                "viewNum": 92,
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=33012",
                "reviewNum": 0
            },
            {
                "name": "《無問西東》穿越四代芳華,體味百态人生",
                "viewNum": 165,
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=984832",
                "reviewNum": 0
            },
            {
                "name": "馮小剛《芳華》延長放映至除夕,年度現象級影片後勁十足",
                "viewNum": 20335,
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32840",
                "reviewNum": 39
            },
            {
                "name": "《芳華》密鑰延至春節,或将再次帶動“帶父母看《芳華》”的熱潮",
                "viewNum": 7900,
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32804",
                "reviewNum": 17
            },
            {
                "name": "第12屆亞洲電影大獎:《妖貓傳》提名領跑,《芳華》入圍最佳影片",
                "viewNum": 4508,
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32771",
                "reviewNum": 3
            },
            {
                "name": "大資料揭秘《前任3》和《芳華》的爆款之路",
                "viewNum": 25001,
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32759",
                "reviewNum": 33
            },
            {
                "name": "《妖貓傳》6項提名領跑亞洲電影大獎,《芳華》入圍最佳影片",
                "viewNum": 17260,
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32756",
                "reviewNum": 25
            },
            {
                "name": "《無問西東》:烈火煉青春,熱血鑄芳華",
                "viewNum": 95,
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=984123",
                "reviewNum": 1
            }
        ],
        "searchType": 4
    }
]
           

對于這種傳回的Json是JsonArray的形式的,如果用Gson 解析,需要自己定義一個類型并傳入fromJson()的第二個參數,即new TypeToken<ArrayList<T>>(){}.getType(); T的類型是Array裡面包裹的類型,自己定義。

對于這種Array中的類型不一緻的情況的,自己實作一個JsonDeserializer,自己實作解析的函數。Json array裡面的類型雖然不一緻,但是類型中,至少有一個變量名是相同的,定義包含公共變量名的類,其他的類型去繼承這個類。 

定義的類如下:

static class BaseResult {
		Integer searchType;
	}

	// searchType = 1
	static class AtcorSearchResult extends BaseResult {
		String chineseName;
		String represent;
		String englishName;
	}

	// searchType = 0
	static class MovieSearchResult extends BaseResult {
		List<InnerMovieResult> list;
	}

	// 電影搜尋結果
	static class InnerMovieResult {
		String overallRating;
		String chineseName;
		String genre;
		String datePublished;
	}

	// searchType = 4
	static class NewsSearchResult extends BaseResult {
		List<InnerNewsSearchResult> list;
	}

	// 新聞搜尋結果
	static class InnerNewsSearchResult {
		String name;
		String viewNum;
		String url;
		String reviewNum;
	}
           

自定義解析器

代碼如下:

static class TypeResultDeserializer implements JsonDeserializer<List<BaseResult>> {

		@Override
		public List<BaseResult> deserialize(JsonElement arg0, Type arg1, JsonDeserializationContext arg2)
				throws JsonParseException {
			// TODO Auto-generated method stub
			JsonArray array = arg0.getAsJsonArray();
			List<BaseResult> list = new ArrayList<>();
			for (JsonElement jsonElement : array) {
				int type = jsonElement.getAsJsonObject().get("searchType").getAsInt();
				if (type == 1) {
					list.add(new Gson().fromJson(jsonElement, AtcorSearchResult.class));
				} else if (type == 0) {
					list.add(new Gson().fromJson(jsonElement, MovieSearchResult.class));
				} else if (type == 4) {
					list.add(new Gson().fromJson(jsonElement, NewsSearchResult.class));
				}
			}
			return list;
		}

	}
           

調用代碼如下:

public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String json = sc.nextLine();

		GsonBuilder gsonb = new GsonBuilder();
		gsonb.registerTypeAdapter(new TypeToken<ArrayList<BaseResult>>() {
		}.getType(), new TypeResultDeserializer());
		gsonb.serializeNulls();
		Gson gson = gsonb.create();
		List<BaseResult> list = gson.fromJson(json, new TypeToken<ArrayList<BaseResult>>() {
		}.getType());
		System.out.println(new Gson().toJson(list));
	}
           

最後的輸出結果是過濾之後的結果:

[
    {
        "list": [
            {
                "overallRating": "9.1",
                "chineseName": "芳華",
                "genre": "劇情,愛情,戰争",
                "datePublished": "2017-12-15大陸上映"
            },
            {
                "overallRating": "0",
                "chineseName": "芳華",
                "genre": "電視劇,劇情",
                "datePublished": ""
            },
            {
                "overallRating": "0",
                "chineseName": "芳華虛度",
                "genre": "劇情",
                "datePublished": ""
            }
        ],
        "searchType": 0
    },
    {
        "chineseName": "葉芳華",
        "represent": "《紅番區》 《狂野三千響》 《誓死追緝令》",
        "englishName": "Françoise Yip",
        "searchType": 1
    },
    {
        "list": [
            {
                "name": "屬于他們的芳華",
                "viewNum": "4",
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=985259",
                "reviewNum": "0"
            },
            {
                "name": "芳華——影評",
                "viewNum": "6",
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=985150",
                "reviewNum": "0"
            },
            {
                "name": "《畢業旅行笑翻天》荷爾蒙激蕩的芳華時代,闡述懵懂的青春",
                "viewNum": "92",
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=33012",
                "reviewNum": "0"
            },
            {
                "name": "《無問西東》穿越四代芳華,體味百态人生",
                "viewNum": "165",
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=984832",
                "reviewNum": "0"
            },
            {
                "name": "馮小剛《芳華》延長放映至除夕,年度現象級影片後勁十足",
                "viewNum": "20335",
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32840",
                "reviewNum": "39"
            },
            {
                "name": "《芳華》密鑰延至春節,或将再次帶動“帶父母看《芳華》”的熱潮",
                "viewNum": "7900",
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32804",
                "reviewNum": "17"
            },
            {
                "name": "第12屆亞洲電影大獎:《妖貓傳》提名領跑,《芳華》入圍最佳影片",
                "viewNum": "4508",
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32771",
                "reviewNum": "3"
            },
            {
                "name": "大資料揭秘《前任3》和《芳華》的爆款之路",
                "viewNum": "25001",
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32759",
                "reviewNum": "33"
            },
            {
                "name": "《妖貓傳》6項提名領跑亞洲電影大獎,《芳華》入圍最佳影片",
                "viewNum": "17260",
                "url": "meituanmovie://www.meituan.com/forum/newsDetail?id=32756",
                "reviewNum": "25"
            },
            {
                "name": "《無問西東》:烈火煉青春,熱血鑄芳華",
                "viewNum": "95",
                "url": "meituanmovie://www.meituan.com/forum/postDetail?postID=984123",
                "reviewNum": "1"
            }
        ],
        "searchType": 4
    }
]