1. 前言
最近,自己在做一個天氣預報Demo,其中利用到了高德地圖中的行政區域查詢接口-----通過url請求,返回相應的json數據,並將此數據轉換爲Java對象。主要是json數據的結構比較複雜,有json數組,而自己這方面的知識涉及得又比較少,所以,折騰了好長一段時間。
2. 需求分析
在Demo中,我是使用了高德地圖中的天氣預報接口,主要實現了兩個功能:1. 根據城市id查詢天氣;2. 根據城市名稱查詢。奈何天氣預報接口中沒有根據城市名稱查詢天氣,所以,我先通過行政區域查詢接口把城市名稱轉換爲城市id,再進行天氣預報接口調用,這樣就完成了上述功能。
由於接口中返回的都是json數據,爲了方便客戶端調用,需要把json數據轉換爲Java對象。
需要將以下的json數據轉換爲java對象:
3. 實戰編碼
將以上json數據抽象爲兩個java對象-----DistrictVO、DistrictResponseVO
DistrictVO:
@Data
public class DistrictVO implements Serializable {
private static final long serialVersionUID = 8444053771784412419L;
private List<String> citycode;
private String adcode;
private String name;
private String center;
private String level;
private List<DistrictVO> districts;
}
DistrictResponseVO:
@Data
public class DistrictResponseVO implements Serializable {
private static final long serialVersionUID = -5812661329615553770L;
private Integer status;
private Integer count;
private String info;
private Integer infocode;
private SuggestionVO suggestion;
private List<DistrictVO> districts;
}
JsonUtil:
public class JsonUtil {
public static DistrictResponseVO doGetDistrict(String json) throws Exception{
DistrictResponseVO districtResponseVO = new DistrictResponseVO();
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(json);
// 獲取json字符串的值
String status = rootNode.get("status") != null ? rootNode.get("status").asText() : "";
String info = rootNode.get("info") != null ? rootNode.get("info").asText() : "";
String infocode = rootNode.get("infocode") != null ? rootNode.get("infocode").asText() : "";
String count = rootNode.get("count") != null ? rootNode.get("count").asText() : "";
districtResponseVO.setStatus(Integer.valueOf(status));
districtResponseVO.setInfo(info);
districtResponseVO.setInfocode(Integer.valueOf(infocode));
districtResponseVO.setCount(Integer.valueOf(count));
// 獲取json數組的值----進行循環遍歷
JsonNode provinceDistrictNode = rootNode.get("districts");
if (null != provinceDistrictNode && provinceDistrictNode.size() > 0) {
ArrayList<DistrictVO> districtList = new ArrayList<>();
for (JsonNode node : provinceDistrictNode) {
DistrictVO districtVO = new DistrictVO();
districtVO.setAdcode(node.get("adcode").asText());
districtVO.setName(node.get("name").asText());
districtVO.setCenter(node.get("center").asText());
districtVO.setLevel(node.get("level").asText());
JsonNode cityDistrictNode = node.get("districts");
List<DistrictVO> districtVOS = new ArrayList<>();
if (null != cityDistrictNode && cityDistrictNode.size() > 0) {
for (JsonNode jsonNode : cityDistrictNode) {
DistrictVO district = new DistrictVO();
district.setAdcode(jsonNode.get("adcode").asText());
district.setName(jsonNode.get("name").asText());
district.setCenter(jsonNode.get("center").asText());
district.setLevel(jsonNode.get("level").asText());
districtVOS.add(district);
}
}
districtVO.setDistricts(districtVOS);
districtList.add(districtVO);
}
districtResponseVO.setDistricts(districtList);
}
return districtResponseVO;
}
將java解析代碼的過程對應如下圖:
解析最外層結構(suggestion沒解析)
解析省級結構
解析市級結構
main()
public static void main(String[] args) {
String str =
"{\"status\":\"1\",\"info\":\"OK\",\"infocode\":\"10000\",\"count\":\"1\","
+ "\"districts\":[{\"adcode\":\"370000\",\"name\":\"山東省\",\"center\":\"117.000923,36.675807\",\"level\":\"province\","
+ "\"districts\":[{\"adcode\":\"370600\",\"name\":\"煙臺市\",\"center\":\"121.391382,37.539297\",\"level\":\"city\"},{\"adcode\":\"371000\",\"name\":\"威海市\",\"center\":\"122.116394,37.509691\",\"level\":\"city\"}]}]}";
try {
DistrictResponseVO districtResponseVO = JsonUtil.doGetDistrict(str);
System.out.println(districtResponseVO);
} catch (Exception e) {
e.printStackTrace();
}
}
使用main()方法進行測試
從我自身角度來看,Json數組解析過程其實並不複雜:首先得知道解析json的一些技術;其次,對於嵌套比較深的json數組,可以一層一層進行解析(畫圖的話,可能會更清晰)。
其實,對於第三方接口返回的數據,我們只需要根據返回的字段給自定義的java對象的屬性一 一對應,然後在調用ObjectMapper.readValue()方法即可。如:
像這樣的話,就可直接解析。至於對那個接口返回的數據爲什麼要進行手動解析,那是因爲,返回的數據中存在着類似於“遞歸”的字段,這個,我也不會處理,所以,暫時就進行手動解析咯!!
【參考博主】
java使用jackson解析複雜json字符串