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 ...)
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)
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);
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);
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>
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...
Aussi simple que cela :
ObjectMapper mapper = new ObjectMapper();
String json = "json value";
MyClass obj = mapper.readValue(json , MyClass .class);