簡體   English   中英

使用 Z7930C951E6009E461E85ED2 從 URL 解析 JSON 數據時返回 null 值

[英]Returned null values when parsing JSON data from URL using Jackson

我正在嘗試從此 url: https://www.topuniversities.com/sites/default/files/qs-rankings-data/397863.txt檢索一些數據。

這是 url 的片段:

    {
  "data": [
    {
      "nid": "294850",
      "url": "/universities/massachusetts-institute-technology-mit",
      "title": "Massachusetts Institute of Technology (MIT)",
      "logo": "<img src=\"https://www.topuniversities.com/sites/default/files/massachusetts-institute-of-technology-mit_410_small_0.jpg\" alt=\"Massachusetts Institute of Technology (MIT) Logo\">",
      "core_id": "410",
      "score": "100",
      "rank_display": "1",
      "country": "United States",
      "region": "North America",
      "stars": "",
      "guide": "<a href=\"/where-to-study/north-america/united-states/guide\" class=\"guide-link\" target=\"_blank\">United States</a>"
    },
    {
      "nid": "297282",
      "url": "/universities/stanford-university",
      "title": "Stanford University",
      "logo": "<img src=\"https://www.topuniversities.com/sites/default/files/stanford-university_573_small_0.jpg\" alt=\"Stanford University Logo\">",
      "core_id": "573",
      "score": "98.6",
      "rank_display": "2",
      "country": "United States",
      "region": "North America",
      "stars": "",
      "guide": "<a href=\"/where-to-study/north-america/united-states/guide\" class=\"guide-link\" target=\"_blank\">United States</a>"
    }, (continue until the end....)

我只對檢索“標題”和“國家/地區”感興趣,但是當我嘗試讀取該值時,我的代碼返回java.lang.NullPointerException

這是我在 main 方法中的 Java 代碼:

ObjectMapper mapper = new ObjectMapper();
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        try {
            System.setProperty("http.agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.29 Safari/537.36");
            UniversityList list = mapper.readValue(new URL("https://www.topuniversities.com/sites/default/files/qs-rankings-data/397863.txt"), UniversityList.class);

            for(University u : list.getUniversity()) {
                // Printing below, gives me null values
                System.out.println("Title: " + u.getTitle());
                System.out.println("Country: " + u.getCountry());
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

這是 DTO class:

class UniversityList{
    private List<University> university;

    public List<University> getUniversity() {
        return university;
    }

    public void setUniversity(List<University> university) {
        this.university = university;
    }

    @Override
    public String toString() {
        return "UniversityList [university=" + university + "]";
    }
}

class University{

    private String title;
    private String country;

    public University() {
    }

    public University(String title, String country) {
        super();
        this.title = title;
        this.country = country;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return "University [title=" + title + ", country=" + country + "]";
    }

如何獲得“Title”和“Country”值? 我不確定它為什么返回 null 值。 任何幫助將不勝感激。 謝謝你。

我懷疑如果你改了名字

private List<University> university;

public List<University> getUniversity() {
    return university;
}

public void setUniversity(List<University> university) {
    this.university = university;
}

更像是

private List<University> data;

public List<University> getData() {
    return data;
}

public void setData(List<University> data) {
    this.data = data;
}

它會填充。 您也可以使用一些注釋來告訴 Jackson“嘿,‘數據’是指我的大學名單”-:)。

Jackson 按名稱映射屬性

一些 Java Guy的建議將通過將嵌套ArrayList的名稱從university調整為data來解決問題(與 JSON 中的相應數組相同)。

當您嘗試從根 object 獲取列表時,會引發java.lang.NullPointerException (NPE)。

問題:發生了什么?

1. 寬容的讀者模式:

您禁用了DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES這告訴 Jackson 將有效的 JSON反序列化為 ZA8CFDE6331BD59EB2AC96F8911C4B66,即使它的某些內容無法映射。

如果不禁用(默認設置) Jackson 將在此處拋出異常( JsonMappingException ),因為 JSON 屬性data無法映射到UniversityList的任何屬性。

2. 沒有屬性被映射,都停留在null

創建了 object list (使用默認/無參數構造函數)。 但是由於它的屬性ArrayList university既沒有被 Jackson 初始化,也沒有設置(映射),它保持null

3.訪問時拋出的NPE:

一旦您的for循環嘗試通過list.getUniversity()訪問該屬性,就會引發 NPE。

NPE的預防:防御性編碼

始終確保您使用的 object (參考)不是 null ,這里是:

if (list != null && list.getUniversity() != null) {
  // now below for loop is safe (no NPE)
  for (University u : list.getUniversity()) {
      // do something with u
  }
}

此外,初始化列表通常是一個好習慣,即使它們是空的。 例如在您的 class UniversityList中聲明:

List<University> university = new ArrayList<>();

小心輕放:Jackson 特點

雖然使用的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES將在此處充當小丑,允許 Jackson 讀取 JSON ,即使映射不適合,您應該格外注意並檢查返回值 見類似問題: https://stackoverflow.com/a/52647349

定義 Jackson 映射

要么使用 Jackson 的默認映射名稱:Java 對象的屬性名稱必須JSON 中的相同。 或者,如果JSON 名稱偏離Java Object 名稱,則使用注釋@JsonProperty來定義它。

在您的情況下,這將是:

@JsonProperty("data")
List<University> university = new ArrayList<>();

定制Jackson

Jackson 提供了許多允許自定義的注釋。 Baeldung 的文章

因此,您也可以將全局禁用的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES替換為 class 特定注釋:

@JsonIgnoreProperties(ignoreUnknown = true)
public class UniversityList {
  // body removed
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM