[英]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。
始終確保您使用的 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<>();
雖然使用的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
將在此處充當小丑,允許 Jackson 讀取 JSON ,即使映射不適合,您應該格外注意並檢查返回值。 見類似問題: https://stackoverflow.com/a/52647349
要么使用 Jackson 的默認映射名稱:Java 對象的屬性名稱必須與JSON 中的相同。 或者,如果JSON 名稱偏離Java Object 名稱,則使用注釋@JsonProperty
來定義它。
在您的情況下,這將是:
@JsonProperty("data")
List<University> university = new ArrayList<>();
Jackson 提供了許多允許自定義的注釋。 見Baeldung 的文章。
因此,您也可以將全局禁用的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
替換為 class 特定注釋:
@JsonIgnoreProperties(ignoreUnknown = true)
public class UniversityList {
// body removed
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.