web-dev-qa-db-fra.com

Analyser une réponse JSON en tant qu'objet

Bonsoir,
Je suis un débutant dans les services Web et je veux juste écrire un client simple qui reçoit simplement les réponses des appels REST.
J'ai téléchargé et ajouté jersey-bundle-1.17.1.jar à mon chemin de génération et j'ai trouvé un morceau de code fonctionnel qui appelle REST vers une URL et renvoie une réponse sous la forme String

import javax.ws.rs.core.MediaType;

import com.Sun.jersey.api.client.Client;
import com.Sun.jersey.api.client.ClientResponse;
import com.Sun.jersey.api.client.WebResource;

public class TestJerseyClient {
    public static void main(String[] args) {
        try {
            Client client = Client.create();
            WebResource webResource = client
                    .resource("http://path/to/service");

            ClientResponse response = webResource
                    .accept(MediaType.APPLICATION_JSON)
                    .get(ClientResponse.class);

            if (response.getStatus() != 200)
                throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());

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

            System.out.println("Output from Server .... \n");
            System.out.println(output);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Mais je ne veux pas faire de manipulations de chaînes pour obtenir les parties de la réponse qui m'intéressent. 

Je préférerais une approche plus structurée, comme obtenir un Object au lieu d'une chaîne
(un objet JSON, un objet Map<K,V>, etc ...) 


TRY # 1 - Map<K,V>

Sep 15, 2013 2:46:13 AM com.Sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class Java.util.Map, and Java type Java.util.Map<Java.lang.String, Java.lang.Object>, and MIME media type application/json; charset=UTF-8 was not found
Sep 15, 2013 2:46:13 AM com.Sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
application/json; charset=UTF-8 ->
  com.Sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
  com.Sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
  com.Sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
  com.Sun.jersey.core.impl.provider.entity.FormProvider
  com.Sun.jersey.core.impl.provider.entity.StringProvider
  com.Sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.Sun.jersey.core.impl.provider.entity.FileProvider
  com.Sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.Sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.Sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.Sun.jersey.core.impl.provider.entity.ReaderProvider
  com.Sun.jersey.core.impl.provider.entity.DocumentProvider
  com.Sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.Sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.Sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.Sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.Sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.Sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.Sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.Sun.jersey.core.impl.provider.entity.EntityHolderReader
  com.Sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.Sun.jersey.json.impl.provider.entity.JSONListElementProvider$General

com.Sun.jersey.api.client.ClientHandlerException: A message body reader for Java class Java.util.Map, and Java type Java.util.Map<Java.lang.String, Java.lang.Object>, and MIME media type application/json; charset=UTF-8 was not found
    at com.Sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.Java:561)
    at com.Sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.Java:535)
    at com.Sun.jersey.api.client.WebResource.handle(WebResource.Java:696)
    at com.Sun.jersey.api.client.WebResource.access$300(WebResource.Java:74)
    at com.Sun.jersey.api.client.WebResource$Builder.get(WebResource.Java:512)
    at rest.TestJerseyClientAdvanced.main(TestJerseyClientAdvanced.Java:36)
8
rtf

Je vous recommande d'utiliser Jackson pour (dé) structurer les réponses JSON. Cela peut être fait en deux étapes comme ci-dessous.

Étape 1. créer un bean Java avec des noms de membre/objet correspondant à la réponse attendue. par exemple, MyResponse.class

Étape 2. utilisez le bean Java lors de la lecture de l'entité à partir de la réponse du client.

private static ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

ClientResponse response =  Client.create(clientConfig).
            resource(uri).accept(MediaType.APPLICATION_JSON).
            header("content-type", MediaType.APPLICATION_JSON).
            get(MY_RESPONSE.class); 
MyResponse output = response.getEntity(MyResponse.class);
10
pNut

Vous pouvez utiliser Genson library.

// register genson in jersey client
ClientConfig cfg = new DefaultClientConfig(GensonJsonConverter.class);
Client client = Client.create(cfg);
WebResource webResource = client.resource("http://path/to/service");

// you can map it to a pojo, no need to have a string or map
SomePojo pojo = webResource
                .accept(MediaType.APPLICATION_JSON)
                .get(SomePojo.class);
7
eugen

Si vous n'avez besoin que de quelques propriétés à partir d'une grande réponse JSON, vous pouvez utiliser le client Jersey et l'entité JsonArray ou JsonObject.

String url = "http://api.goeuro.com/api/v2/position/suggest/en/";
String city = "New York";

Client client = ClientBuilder.newClient();
WebTarget webTarget = client.register(JsonProcessingFeature.class).target(url);
JsonArray jsonArray = webTarget.path(city)
    .request(MediaType.APPLICATION_JSON_TYPE).get(JsonArray.class);

for (JsonObject jsonObject : jsonArray.getValuesAs(JsonObject.class)) {
    JsonObject geoPosition = jsonObject.getJsonObject("geo_position");
    System.out.println(Arrays.asList(
        jsonObject.getString("name"), jsonObject.getString("type"),
        geoPosition.get("latitude"), geoPosition.get("longitude")));
}

Dépendances Maven

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.22.1</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-processing</artifactId>
    <version>2.22.1</version>
</dependency>
4
Yuriy Tumakha

voir cet exemple ... cliquez sur ce lien pour plus d'informations

// The request also includes the userip parameter which provides the end
// user's IP address. Doing so will help distinguish this legitimate
// server-side traffic from traffic which doesn't come from an end-user.
URL url = new URL(
    "https://www.websitelink.com//folderresponsedata
    + "q=Paris%20Hilton&userip=USERS-IP-ADDRESS");
URLConnection connection = url.openConnection();
connection.addRequestProperty("Referer", /* Enter the URL of your site here */);

String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while((line = reader.readLine()) != null) {
 builder.append(line);
}

JSONObject json = new JSONObject(builder.toString());
// now have some fun with the results...
0
Nambi

Aussi simple que cela : 

    ObjectMapper mapper = new ObjectMapper();
    String json = "json value";
    MyClass obj = mapper.readValue(json , MyClass .class);
0
Rzv Razvan