web-dev-qa-db-ja.com

ポストリクエストからJAX-RSクライアントの応答本文を読み取る

モバイルアプリとWebサービスの間に何らかのプロキシが存在するため、ポストリクエストを発行する際の応答に困惑しています。ステータス200:OKの応答を受け取ります。ただし、JSON応答本文を検索/抽出することはできません。

    Client client = ClientBuilder.newClient();
    WebTarget webTarget = client.target(WEBSERVICE_BASE_LOCATION + "mobileDevices?operatorCode=KPNSCP");
    String jsonString = "{\"osVersion\":\"4.1\",\"apiLevel\":16,\"devicePlatform\":\"Android\"}";
    Builder builder = webTarget.request();
    Response response = builder.post(Entity.json(jsonString));

JAX-RSを使用しています。誰かがサーバーの応答からJSON本体(String)を抽出するためのヒントを提供できますか?

59
user2657714

これを試して:

String output = response.getEntity(String.class);

編集

@Martin Spamerに感謝します。これは、Jersey 1.x jarのみで機能することを示しています。 Jersey 2.xの場合

String output = response.readEntity(String.class);
134
Juned Ahsan

私はjaxrs-ri-2.16の解決策を見つけました-単に使用する

String output = response.readEntity(String.class)

これにより、期待どおりにコンテンツが配信されます。

14
col.panic

私のユースケースでは、 Glassfish Jerseyクライアント応答オブジェクトをモックできない 質問で説明されているように、次のエラーメッセージが原因で失敗するサーバー側ユニットテストを書いていたため、以前の回答はいずれも機能しませんでした:

Java.lang.IllegalStateException: Method not supported on an outbound message.
at org.glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.Java:145)
at ...

この例外は、次のコード行で発生しました。

String actJsonBody = actResponse.readEntity(String.class);

修正は、問題のあるコード行を次のように変更することでした。

String actJsonBody = (String) actResponse.getEntity();
10
entpnerd

readEntityを使用するコードを呼び出す単体テストを実行しようとしても、同じ問題がありました。本番コードでgetEntityを使用することはできません。これは、ボディのコンテンツではなくByteInputStreamを返すだけで、単体テストでのみヒットする本番コードを追加する方法がないためです。

私の解決策は、応答を作成し、Mockitoスパイを使用してreadEntityメソッドをモックアウトすることでした。

Response error = Response.serverError().build();
Response mockResponse = spy(error);
doReturn("{jsonbody}").when(mockResponse).readEntity(String.class);

when(mockResponse.readEntity(String.class)オプションは同じIllegalStateExceptionをスローするため使用できないことに注意してください。

お役に立てれば!

4
Cheefachi

コードの改訂を実現することで、読み取り方法が機能しなかった理由を見つけました。問題は、私のプロジェクトがjersey 1.xを使用した依存関係の1つでした。バージョンを更新し、クライアントを調整すると動作します。

次のMaven依存関係を使用します。

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

よろしく

カルロス・セペダ

0

ドキュメントによると、Jax rs 2.0のgetEntityメソッドはInputStreamを返します。 InputStreamからJSON形式の文字列に変換する必要がある場合は、2つの形式をキャストする必要があります。たとえば、私の場合、次のメソッドを実装しました。

    private String processResponse(Response response) {
    if (response.getEntity() != null) {
        try {
            InputStream salida = (InputStream) response.getEntity();
            StringWriter writer = new StringWriter();
            IOUtils.copy(salida, writer, "UTF-8");
            return writer.toString();
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }
    return null;
}

このメソッドを実装した理由。多くの開発者が次のメソッドを使用してjaxrsのバージョンで同じ問題を抱えているというdiffersetブログの読み取りのため

String output = response.readEntity(String.class)

そして

String output = response.getEntity(String.class)

最初はcom.Sun.jerseyライブラリのjersey-clientを使用して動作し、2番目はorg.glassfish.jersey.coreのjersey-clientを使用して動作します。

これは私に提示されたエラーです:org.glassfish.jersey.client.internal.HttpUrlConnector $ 2はJava.lang.Stringにキャストできません

次のMaven依存関係を使用します。

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

私が知らないのは、readEntityメソッドが機能しない理由です。このソリューションを使用できることを願っています。

カルロス・セペダ

0