web-dev-qa-db-de.com

Antworttext in JAX-RS-Client aus einer Post-Anfrage lesen

Da wir eine Art Proxy zwischen einer mobilen App und einem Webdienst haben, wundert uns die Antwort, wenn wir eine Post-Anfrage stellen. Wir erhalten eine Antwort mit dem Status 200: OK. Wir können den JSON-Antworttext jedoch nicht finden/extrahieren.

    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));

Wir verwenden JAX-RS. Kann jemand bitte einige Hinweise geben, um den JSON-Body (String) aus der Serverantwort zu extrahieren?

59
user2657714

Versuche dies:

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

EDIT

Vielen Dank an @Martin Spamer, um zu erwähnen, dass es nur für Jersey 1.x-Gläser funktioniert. Für Jersey 2.x verwenden

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

Ich habe gerade eine Lösung für jaxrs-ri-2.16 gefunden - benutze sie einfach

String output = response.readEntity(String.class)

dies liefert den Inhalt wie erwartet.

14
col.panic

Für meinen Anwendungsfall hat keine der vorherigen Antworten funktioniert, da ich einen serverseitigen Komponententest geschrieben habe, der aufgrund der folgenden Fehlermeldung fehlgeschlagen ist, wie in der Frage Glassfish Jersey Client-Antwortobjekt kann nicht nachgeahmt werden beschrieben:

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

Diese Ausnahme trat in der folgenden Codezeile auf:

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

Die Lösung bestand darin, die problematische Codezeile in Folgendes umzuwandeln:

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

Ich hatte auch das gleiche Problem, als ich versuchte, einen Unit-Test-Aufrufcode auszuführen, der readEntity verwendet. Ich kann getEntity nicht im Produktionscode verwenden, da dies nur ein ByteInputStream und nicht den Inhalt des Körpers zurückgibt, und ich kann auf keinen Fall Produktionscode hinzufügen, der nur in Komponententests gefunden wurde.

Meine Lösung bestand darin, eine Antwort zu erstellen und dann einen Mockito-Spion zu verwenden, um die readEntity -Methode zu verspotten:

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

Beachten Sie, dass Sie die Option when(mockResponse.readEntity(String.class) nicht verwenden können, da dies dasselbe IllegalStateException auslöst.

Hoffe das hilft!

4
Cheefachi

Als ich die Überarbeitung des Codes realisierte, fand ich die Ursache, warum die Lesemethode bei mir nicht funktionierte. Das Problem war, dass eine der Abhängigkeiten, die mein Projekt verwendete, Trikot 1.x. Aktualisieren Sie die Version, passen Sie den Client an und es funktioniert.

Ich benutze die folgende Maven-Abhängigkeit:

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

Grüße

Carlos Cepeda

0

Entsprechend der Dokumentation gibt die Methode getEntity in Jax rs 2.0 einen InputStream zurück. Wenn Sie mit dem JSON-Format in InputStream to String konvertieren müssen, müssen Sie die beiden Formate umwandeln. In meinem Fall habe ich zum Beispiel die folgende Methode implementiert:

    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;
}

warum ich diese Methode implementiert habe. Da eine Lektüre in verschiedenen Blogs dazu führt, dass viele Entwickler dasselbe Problem haben, wenn die Version in jaxrs die nächsten Methoden verwendet

String output = response.readEntity(String.class)

und

String output = response.getEntity(String.class)

Der erste funktioniert mit dem Trikot-Client aus der com.Sun.jersey-Bibliothek und der zweite mit dem Trikot-Client aus org.glassfish.jersey.core.

Dies ist der Fehler, der mir angezeigt wurde: org.glassfish.jersey.client.internal.HttpUrlConnector $ 2 kann nicht in Java.lang.String umgewandelt werden

Ich benutze die folgende Maven-Abhängigkeit:

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

Was ich nicht weiß, ist, warum die readEntity-Methode nicht funktioniert. Ich hoffe, Sie können die Lösung verwenden.

Carlos Cepeda

0