2017-06-07 4 views
2

したがって、私はSpringブート1.5.3を使用しており、次のJsonの一部にしようとしています - つまりAccountIdUsername - (実際はoData v2 restTemplate.exchangeを使用してクラスに)するSAP NetWeaverインスタンスから獲得インターフェイス:春Resttemplate:@JsonIgnoreを使用して解析すると値がNULLになる

{ 
    "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 +'\'' + 
       '}'; 
    } 
} 

ここでは私が試してみる方法です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>を使用してドキュメントのようにそれを解析しようとしたが、これは単に空のクラス(アカウントID = nullで、ユーザ名=ヌル)につながるので、私はResponseEntity<String>を使用して上記の方法を試してみましたレスポンスを文字列表現に解析するときに何が得られるかを見ることができます。そうすれば、上記のjsonが正しく返されていることを確認できます。値は確かにそこにあります。解析する必要がありますが、この問題を回避する方法はありません。

ここで私を助けてくれることを願っています!

edit:getForObjectが動作するかもしれませんが、これは私が基本認証を使用しなければならないので、私にとっては別の問題につながります。実際には実行可能ではありません。 AccountIDはうまくいかなかった。

+0

私の推測では、問題はアカウントIDとユーザー名をラップするJSONのオブジェクト "d"です。これは、実際には、 "AccountId"と "Username"という文字列を含む "d"という名前のクラスに変換されます。テストの目的で、PortalAccountの代わりにクラス "d"の名前を付けてみてください。 –

+0

また、PortalAccountクラスの@JsonTypeName( "d")を試してください。 –

+0

だから、getBody()には質問に追加されたjson iが含まれています。今度はクラスを "d"に変更しようとしましたが、同じ動作になります。また、私はJsonTypeName( "d")を 'd'-Classに追加し、PortalAccount-re-refactoerd PortalAccount-Classに成功せずに試してみました:/ –

答えて

2

ですから、Christian Zieglersのコメントと回答は部分的に正しいです。

検索したJsonからクラス構造をマッピングできるようにする必要があります。

ので、それを動作させるために、私見最も簡単な方法は、代わりに、ラッパーオブジェクトを作成する、ことwoud:

  1. はあなたの@JsonIgnoreProperties注釈を削除します。オブジェクトマッパーでこれを行います。

  2. 次に、PortalAccountクラスにJacksons @JsonRootNameプロパティを追加し、値をdに設定します。あなたはそれを呼び出すとき、あなたはあなたのrootElementのラップを解除するために、あなたのObjectmapperは(ジャクソン2を仮定)を設定する必要が今

    @JsonRootName(value = "d") 
    public class PortalAccount implements Serializable{ 
        public PortalAccount() { 
        } 
    
        @JsonProperty("AccountID") 
        public String accountID; 
    
        @JsonProperty("Username") 
        public String username; 
    
        ... 
    } 
    

    :このような

@JsonRootName(value = "d"):今、あなたのクラスには、これだけのアノテーションを持っている必要がありますこのように(そして未知の特性を無視する):

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メソッドを使用してみてください。 「「たAccountId」という名前の2つのプロパティが含まれている「D」

@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は型のプロパティを含むクラスを必要とすること、であると:ここ

は一例ですユーザー名 "を入力します。

したがって、基本的にオブジェクト "d"の内容のみを解析する必要があります。

Parsing a subset of JSON in Java using Jacksonは、それがどのように行われたかを示します。

+0

ありがとうございました!私たちはここで正しい方法で行ってきたと思います。他の答えは受け入れられました。完全に動作するサンプルがあり、 'JsonRootName'の使用はラッパークラスを作成するよりもエレガントです。 –

+0

それは確かです。私は@JsonRootNameについて知らなかった。非常に素晴らしい! –

関連する問題