Clients REST pour Java?
Avec JSR 311 et ses implémentations, nous avons un standard puissant pour exposer des objets Java via Rest. Cependant, du côté client, il semble y avoir quelque chose qui manque qui est comparable à Apache Axis pour SOAP-quelque chose qui cache le service Web et récupère les données de manière transparente vers les objets Java.
Comment créez-vous des clients Java RESTful? Utilisation de HTTPConnection et analyse manuelle du résultat? Ou des clients spécialisés pour par exemple Jersey ou Apache CXR?
18 answers
C'est une vieille question (2008) donc il y a beaucoup plus d'options maintenant qu'il n'y en avait alors:
- Apache CXF a trois options client REST différentes
- Maillot (mentionné ci-dessus).
- Spring a aussi son propre RestTemplate
- Commons HTTP Client créez le vôtre pour les anciens projets Java.
mise à JOUR circa 2014:
-
Async-http-client par Sonatype. Ning Async-http-client.
Le petit nouveau sur le bloc qui fournit le support NIO (bien que honnêtement, je ne pense pas que cela améliore vraiment les performances pour les clients comme il le fait pour les serveurs).
- Composants HTTP Apache (4.2) Adaptateur Fluent - Meilleur que l'ancien client HTTP Commons 3 et plus facile à utiliser pour créer votre propre client REST. Vous aurez à utiliser quelque chose commeJackson pour l'analyse JSON support et vous pouvez utilisercomposants HTTP URIBuilder pour construire des URI de ressources similaires au client Rest Jersey/JAX-RS. Les composants HTTP prennent également en charge NIO, mais je doute que vous obteniez de meilleures performances que BIO étant donné la nature de la demande courte de REST.
MISE À JOUR 2016:
- OkHttp - Prend en charge les nouveaux protocoles HTTP (SPDY et HTTP2). Fonctionne sur Android. Malheureusement il n'offre pas un vrai option asynchrone basée sur une boucle de réacteur (voir les composants Ning et HTTP ci-dessus). Cependant, si vous utilisez le protocole HTTP2 plus récent, cela pose moins de problème (en supposant que le nombre de connexions est un problème).
- Rénovation - Créera-t-il automatiquement des clients basés sur des talons d'interface similaires à certaines extensions Jersey et CXF. Utilise OkHttp.
- Apache HttpComponents 5 aura soi-disant le support HTTP2
Une mise en garde sur la sélection des clients HTTP/REST. Assurez-vous de vérifier ce que votre cadre stack utilise pour un client HTTP, comment il fait le threading, et utilise idéalement le même client s'il en offre un. C'est si vous utilisez quelque chose comme Vert.x ou Play vous voudrez peut-être essayer d'utiliser son client de support pour participer à la boucle de bus ou de réacteur fournie par le framework... sinon, préparez-vous à des problèmes de threading éventuellement intéressants.
Comme je l'ai mentionné dans ce threadJ'ai tendance à utiliser Jersey qui implémente JAX-RS et est livré avec un bon client REST. La bonne chose est que si vous implémentez vos ressources RESTful à l'aide de JAX-RS, le client Jersey peut réutiliser les fournisseurs d'entités tels que pour JAXB/XML/JSON/Atom et ainsi de suite - afin que vous puissiez réutiliser les mêmes objets côté serveur que vous utilisez sur le test unitaire côté client.
Par exemple voici un cas de test unitaire du Apache Camel project qui recherche des charges utiles XML à partir d'une ressource RESTful (en utilisant les points de terminaison d'objet JAXB). La méthode resource (uri) est définie dans cette classe de base qui utilise simplement l'API client Jersey.
Par exemple
clientConfig = new DefaultClientConfig();
client = Client.create(clientConfig);
resource = client.resource("http://localhost:8080");
// lets get the XML as a String
String text = resource("foo").accept("application/xml").get(String.class);
BTW j'espère que la future version de JAX-RS ajoutera une belle API côté client dans le sens de celle de Jersey
Vous pouvez utiliser les API Java SE standard:
private void updateCustomer(Customer customer) {
try {
URL url = new URL("http://www.example.com/customers");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/xml");
OutputStream os = connection.getOutputStream();
jaxbContext.createMarshaller().marshal(customer, os);
os.flush();
connection.getResponseCode();
connection.disconnect();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
Ou vous pouvez utiliser les API client REST fournies par les implémentations JAX-RS telles que Jersey. Ces API sont plus faciles à utiliser, mais nécessitent des jar supplémentaires sur votre chemin de classe.
WebResource resource = client.resource("http://www.example.com/customers");
ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "<customer>...</customer.");
System.out.println(response);
Pour plus d'informations, voir:
Vous pouvez également vérifier Restlet qui a des capacités complètes côté client, plus orientées REST que les bibliothèques de niveau inférieur telles que HttpURLConnection ou Apache HTTP Client (que nous pouvons exploiter en tant que connecteurs).
Meilleures salutations, Jérôme Louvel
Si vous souhaitez uniquement appeler un service REST et analyser la réponse, vous pouvez essayer Rassurez-vous
// Make a GET request to "/lotto"
String json = get("/lotto").asString()
// Parse the JSON response
List<String> winnderIds = with(json).get("lotto.winners.winnerId");
// Make a POST request to "/shopping"
String xml = post("/shopping").andReturn().body().asString()
// Parse the XML
Node category = with(xml).get("shopping.category[0]");
Vous pouvez essayer de Rapa. Laissez-nous savoir vos commentaires sur le même. Et n'hésitez pas à enregistrer les problèmes ou les fonctionnalités attendues.
Je voudrais souligner 2 autres options:
- Restfulie , basé sur le framework web VRaptor, a des implémentations côté serveur et côté client avec un très bon support hypermédia.
- RESTEasy a une implémentation client basé sur un proxy JAX-RS .
J'ai récemment essayé la bibliothèque Retrofit de square, c'est génial et vous pouvez appeler votre API rest très facilement. La configuration basée sur les annotations nous permet de nous débarrasser du codage des plaques de chaudière.
J'utilise Apache HttpClient pour gérer tout le côté HTTP des choses.
J'écris des analyseurs SAX XML pour le contenu XML qui analyse le XML dans votre modèle d'objet. Je crois qu'Axis2 expose également les méthodes XML -> Model (Axis 1 a caché cette partie, de manière agaçante). Les générateurs XML sont trivialement simples.
Il ne faut pas longtemps pour coder, et est assez efficace, à mon avis.
Essayez JdkRequest
de jcabi-http (je suis un développeur). Voici comment cela fonctionne:
String body = new JdkRequest("http://www.google.com")
.header("User-Agent", "it's me")
.fetch()
.body()
Consultez cet article de blog pour plus de détails: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html
OkHttp est léger et puissant lorsqu'il est combiné avec Retrofit ainsi. Cela fonctionne bien pour l'utilisation générale de Java ainsi que sur Android.
OkHttp: http://square.github.io/okhttp/
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
Rénovation: http://square.github.io/retrofit/
public interface GitHubService {
@GET("/users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Puisque personne ne l'a mentionné, en voici une autre: Feindre, qui est utilisé par Printemps Cloud.
Depuis un moment maintenant, j'utilise Resty :
JSONResource jsonResource = new Resty().json(uri);
On peut trouver quelques exemples ici.
Bien qu'il soit simple de créer un client HTTP et de faire un reuest. Mais si vous souhaitez utiliser certains clients générés automatiquement, Vous pouvez utiliser WADL pour décrire et générer du code.
Vous pouvez utiliser RestDescribe pour générer et compiler WSDL, vous pouvez générer des clients en php, ruby, python, java et C# en utilisant ceci. Il génère du code propre et il y a un bon changement que vous devez modifier un peu après la génération de code, vous pouvez trouver une bonne documentation et des pensées sous-jacentes derrière l'outil ici.
Il y a peu d'outils intéressants et utiles WADL mentionnés sur wintermute.
J'ai écrit une bibliothèque qui mappe une interface java à un service REST JSON distant:
Https://github.com/ggeorgovassilis/spring-rest-invoker
public interface BookService {
@RequestMapping("/volumes")
QueryResult findBooksByTitle(@RequestParam("q") String q);
@RequestMapping("/volumes/{id}")
Item findBookById(@PathVariable("id") String id);
}
Essayer de regarder http-repos-client
Https://github.com/g00dnatur3/http-rest-client
Voici un exemple simple:
RestClient client = RestClient.builder().build();
String geocoderUrl = "http://maps.googleapis.com/maps/api/geocode/json"
Map<String, String> params = Maps.newHashMap();
params.put("address", "beverly hills 90210");
params.put("sensor", "false");
JsonNode node = client.get(geocoderUrl, params, JsonNode.class);
La bibliothèque s'occupe de la sérialisation et de la liaison json pour vous.
Voici un autre exemple,
RestClient client = RestClient.builder().build();
String url = ...
Person person = ...
Header header = client.create(url, person);
if (header != null) System.out.println("Location header is:" + header.value());
Et un dernier exemple,
RestClient client = RestClient.builder().build();
String url = ...
Person person = client.get(url, null, Person.class); //no queryParams
Santé!
Exemples de client jersey Rest:
Ajouter une dépendance:
<!-- jersey -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20090211</version>
</dependency>
ForGetMethod et en passant deux paramètres:
Client client = Client.create();
WebResource webResource1 = client
.resource("http://localhost:10102/NewsTickerServices/AddGroup/"
+ userN + "/" + groupName);
ClientResponse response1 = webResource1.get(ClientResponse.class);
System.out.println("responser is" + response1);
GetMethod passant un paramètre et obtenant une réponse de List:
Client client = Client.create();
WebResource webResource1 = client
.resource("http://localhost:10102/NewsTickerServices/GetAssignedUser/"+grpName);
//value changed
String response1 = webResource1.type(MediaType.APPLICATION_JSON).get(String.class);
List <String > Assignedlist =new ArrayList<String>();
JSONArray jsonArr2 =new JSONArray(response1);
for (int i =0;i<jsonArr2.length();i++){
Assignedlist.add(jsonArr2.getString(i));
}
Au-dessus, il renvoie une Liste que nous acceptons en tant que Liste, puis la convertissons en tableau Json, puis en tableau Json en Liste .
Si la requête Post passe l'objet Json en paramètre:
Client client = Client.create();
WebResource webResource = client
.resource("http://localhost:10102/NewsTickerServices/CreateJUser");
// value added
ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class,mapper.writeValueAsString(user));
if (response.getStatus() == 500) {
context.addMessage(null, new FacesMessage("User already exist "));
}
Vous pouvez utiliser java. net. URL
public class URL {
public URL(java.lang.String s)
throws java.net.MalformedURLException {}
public java.net.URLConnection
openConnection() throws java.io.IOException {}
...
}
À partir d'une URL, vous pouvez créer une HttpURLConnection qui vous permet d'invoquer des
requests. Here’s an example of doing a simple GET request:
URL url = new URL("http://example.com/customers/1");
connection = (HttpURLConnection) getUrl.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/xml");
if (connection.getResponseCode() != 200) {
throw new RuntimeExceptioin("Operation failed: "
+ connection.getResponseCode());
}
System.out.println("Content-Type:
" + connection.getContentType());
BufferedReader reader = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
connection.disconnect();