2016-09-08 2 views
0

RESTEasyクライアントを使用してAPIからJSON文字列を取得しています。RESTEasyクライアントでJSON応答の特定のノードを抽出します。

{ 
    "foo1" : "", 
    "foo2" : "", 
    "_bar" : { 
    "items" : [ 
     { "id" : 1 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 2 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 3 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 4 , "name" : "foo", "foo" : "bar" } 
    ] 
    } 
} 

今、私はオブジェクト・マッピングのための唯一のitemsノードを抽出したい:JSONペイロードは次のようになります。 JSONレスポンス本体を傍受し、ルートノードとしてitemsに変更するにはどうすればよいですか?

APIメソッドにRESTEasy proxy frameworkを使用しています。

RESTクライアントコード:

ResteasyWebTarget target = client.target("https://"+server); 
target.request(MediaType.APPLICATION_JSON); 
client.register(new ClientAuthHeaderRequestFilter(getAccessToken())); 
MyProxyAPI api = target.proxy(MyProxyAPI.class); 
MyDevice[] result = api.getMyDevice(); 

RESTEasyのプロキシインタフェース:

public interface MyProxyAPI { 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    @Path("/device") 
    public MyDevice[] getMyDevices(); 

    ... 
} 
+0

JavaScriptオブジェクトに変換し、それをオブジェクトとして取得します。 – SaviNuclear

+0

'items'がルートであること、あるいはメッセージの他の要素をマッピングしたくないことは重要ですか? RestEasyドキュメントを見て、JAXBプロバイダを介してJava Beanへの自動マーシャリング/アンマーシャリングを使用していますか? – dbreaux

+0

@dbreauxはい、他の要素をマップしたくないだけです。単純化された実装コードについては、私のOPの編集を参照してください。もちろん、メッセージ本文を変更するプロバイダーを登録することはできますが、そのプロバイダーの実装がどのように見えるのだろうかと思います。 –

答えて

1

あなたはReaderInterceptorを作成し、JSONを操作するためにジャクソンを使用することができます。

public class CustomReaderInterceptor implements ReaderInterceptor { 

    private ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public Object aroundReadFrom(ReaderInterceptorContext context) 
         throws IOException, WebApplicationException { 

     JsonNode tree = mapper.readTree(context.getInputStream()); 
     JsonNode items = tree.get("_bar").get("items"); 
     context.setInputStream(new ByteArrayInputStream(mapper.writeValueAsBytes(items))); 
     return context.proceed(); 
    } 
} 

からログインあなたの上に作成したReaderInterceptorClient

Client client = ClientBuilder.newClient(); 
client.register(CustomReaderInterceptor.class); 
+1

実際には、別の質問に対するあなたの回答の1つは、これに対する簡単な解決策かもしれません:http://stackoverflow.com/a/38352932/796761 – dbreaux

+0

@dbreauxそれを思い出させてくれてありがとう:) –

+1

dbreaux (JSONを取得し、ジャクソンツリーを介して目的のノードにアクセスする)は、私が今まで回避策としてやっていたことです。もちろんこれはプロキシフレームワークでは機能しません。私は迎撃を試みます。ありがとう。 –

1

私が気にするよりも多くのフィールドを含むメッセージに対して、複雑なJavaクラスを定義する必要はないという同じ希望がありました。私のJEEサーバー(WebSphere)では、Jacksonが基礎となるJSON実装であり、RESTEasyのオプションと思われます。ジャクソンは、未知のJSONフィールドを無視することができ@JsonIgnoreProperties注釈を持っています

import javax.xml.bind.annotation.XmlType; 
import org.codehaus.jackson.annotate.JsonIgnoreProperties; 

@XmlType 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class JsonBase {} 

他のJSONの実装は、同様の機能を持っている場合、私は知りませんが、それは確かに自然なユースケースと思われます。

(私もこれと私のWebSphere環境に関連するいくつかの他のJAX-RSの技術とblog postを書きました。)

+0

それは良い解決策ですが、OPによって記述された状況ではうまくいかないかもしれません。 'items'ノードは' _bar'の子であり、ルートノードの子ではありません。 –

+0

これを行うには、ほとんど何も持たないラッパークラスを定義します。私の場合、これは選択肢よりも優れていました。 – dbreaux

+0

意味があります。 Upvoted。 –

関連する問題