2017-06-07 91 views
2

因此,我使用的是Spring Boot 1.5.3,並嘗試使用以下Json的一部分 - - 即AccountIdUsername - (實際上,它是一個oData v2接口從角色的SAP NetWeaver實例得到)爲一類使用restTemplate.exchange:Spring Resttemplate:使用@JsonIgnore解析導致值爲空

{ 
    "d":{ 
     "__metadata":{ 
     "id":"...", 
     "uri":"...", 
     "type":"...." 
     }, 
     "AccountID":"0100000001", 
     "Username":"[email protected]", 
     "Partners":{ 
     "__deferred":{ 
      "uri":"Navigationproperty" 
     } 
     } 
    } 
} 

我班建立這樣的,因爲一開始我只是想獲得帳戶ID,名稱:

@JsonIgnoreProperties(ignoreUnknown = true) 
public class PortalAccount implements Serializable{ 

    public PortalAccount() { 
    } 

    @JsonProperty("AccountID") 
    public String accountID; 

    @JsonProperty("Username") 
    public String username; 

    public String getPortalAccountID() { 
     return accountID; 
    } 

    public void setPortalAccountID(String portalAccountID) { 
     this.accountID = portalAccountID; 
    } 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @Override 
    public String toString() { 
     return "Account{" + 
       "accountID='" + accountID + '\'' + 
       ", username='" + username +'\'' + 
       '}'; 
    } 
} 

以下是我嘗試cal的方式l在:

 RestTemplate restTemplate = new RestTemplate(); 
     HttpHeaders httpHeaders = this.createHeaders(); 
     ResponseEntity<String> response; 
     response = restTemplate.exchange(uri,HttpMethod.GET,new HttpEntity<Object>(httpHeaders),String.class); 
     ObjectMapper mapper = new ObjectMapper(); 

     PortalAccount acc = mapper.readValue(response.getBody(), PortalAccount.class); 

我第一次嘗試分析它直接像使用ResponseEntity<PortalAccount>的文檔,但這只是導致一個空的類(帳戶= NULL,用戶名= NULL),所以我想上面使用ResponseEntity<String>方式看看我在將響應解析爲字符串表示時得到的內容。這樣,我可以確保上面的json被正確地返回,它是這樣的。因此,值肯定存在,它必須是解析的問題,但我很遺憾沒有解決這個問題。

我希望你能幫助我在這裏!

編輯:作爲一個答案提到,getForObject可能會工作,但這導致我的其他問題,因爲我不得不使用基本身份驗證,所以它不是真正可行的。我也嘗試套管問題,命名變量accountID或AccountID,它沒有解決。

+0

我的猜測是,問題是JSON中包含AccountId和Username的對象「d」。這實際上將轉換爲名爲「d」的類,其中包含字符串「AccountId」和「用戶名」。出於測試目的,嘗試命名您的類「d」而不是PortalAccount。 –

+0

另外,嘗試@JsonTypeName(「d」)類PortalAccount –

+0

所以,是的,getBody()包含我添加到問題的json。現在我嘗試將課程更改爲「d」,這導致了相同的行爲。另外,我嘗試將JsonTypeName(「d」)添加到'd'-Class和重新生成的PortalAccount-Class中,但沒有成功:/ –

回答

2

因此,Christian Zieglers評論和回答是部分正確的。

您需要確保您的類結構可以從檢索到的Json進行映射。

所以,使其工作時,恕我直言,最簡單的方法是woud,而不是創建一個包裝對象:

  1. 刪除您@JsonIgnoreProperties註解。我們將使用對象映射器來做到這一點。

  2. 然後,將Jacksons @JsonRootName屬性添加到您的類PortalAccount並將值設置爲d。現在你的類應該只有這一個註解:

@JsonRootName(value = "d")這樣的:

@JsonRootName(value = "d") 
public class PortalAccount implements Serializable{ 
    public PortalAccount() { 
    } 

    @JsonProperty("AccountID") 
    public String accountID; 

    @JsonProperty("Username") 
    public String username; 

    ... 
} 

現在,當你調用它,你必須設置你的Objectmapper(假設傑克遜2),以解開您的rootElement的(而忽略未知屬性)是這樣的:

objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); 
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

所以你的整個呼叫是這樣的:

RestTemplate restTemplate = new RestTemplate(); 
HttpHeaders httpHeaders = this.createHeaders(); 
ResponseEntity<String> response; 
response = restTemplate.exchange(uri,HttpMethod.GET,new HttpEntity<Object>(httpHeaders),String.class); 
ObjectMapper mapper = new ObjectMapper(); 
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); 
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

PortalAccount acc = mapper.readValue(response.getBody(), PortalAccount.class); 

這裏重要的是,如上所述,@JsonRootName屬性,因爲沒有它,UNWRAP_ROOT_VALUE功能將無法正常工作。

希望這會有所幫助!

+0

謝謝你,像魅力一樣工作! :) –

0

您可以嘗試使用getForObject方法來代替交換。

下面是一個例子:

@JsonIgnoreProperties(ignoreUnknown = true) 

public class Page { 

    private String name; 
    private String about; 
    private String phone; 
    private String website; 

    public String getName() { 
     return name; 
    } 

    public String getAbout() { 
     return about; 
    } 

    public String getPhone() { 
     return phone; 
    } 

    public String getWebsite() { 
     return website; 
    } 

} 


RestTemplate restTemplate = new RestTemplate(); 
Page page = restTemplate.getForObject("http://graph.facebook.com/pivotalsoftware", Page.class); 
System.out.println("Name: " + page.getName()); 
System.out.println("About: " + page.getAbout()); 
System.out.println("Phone: " + page.getPhone()); 
System.out.println("Website: " + page.getWebsite()); 
+0

可悲的是我不能,因爲我需要基本認證,這讓我遇到了其他問題。 (我希望通過get/postforobject和basi auth找到一個工作示例,說實話)。 –

2

的問題是,根據您的JSON的ObjectMapper需要包含其中包含名爲「帳戶ID」和「兩個屬性型「d」的屬性的類用戶名」。

所以,你基本上只需要解析對象「d」的內容。

Parsing a subset of JSON in Java using Jackson描述了它是如何完成的。

+0

謝謝你的幫助!我認爲我們在這裏已經走上了正確的道路。剛剛接受了其他答案,因爲它有一個完整的工作示例,並且使用'JsonRootName'比創建包裝類更優雅。 –

+0

確實如此。我不知道@JsonRootName。非常好! –

相關問題