Comment créez-vous un client REST pour Java? [fermé]

248

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 qu'il manque quelque chose qui soit comparable à Apache Axis pour SOAP - quelque chose qui cache le service Web et rassemble les données de manière transparente vers les objets Java.

Comment créez-vous des clients Java RESTful? Vous utilisez HTTPConnection et l'analyse manuelle du résultat? Ou des clients spécialisés pour par exemple Jersey ou Apache CXR?

Yaba
la source
Je viens de trouver Apache Wink dans l'incubateur Apache. Cela pourrait être un projet intéressant pour créer des serveurs et des clients REST.
Yaba
2
vérifiez ceci: igorpolevoy.blogspot.com/2011/01/java-rest-with-ease.html merci igor
ipolevoy
Découvrez [Repos] ( code.google.com/p/resting ). Il promet d'invoquer les services REST et de créer une liste d'objets à partir d'une réponse XML / JSON / YAML en une seule étape.
neel
Le repos a des problèmes avec les requêtes POST.
RyanBrady
2
Vous pouvez le faire d'une manière très simple avec resteasy (par Jboss). J'ai écrit un article de blog sur la façon de développer un client Java REST si vous voulez un guide de démarrage. Quoi qu'il en soit, il existe des centaines d'alternatives en Java.
Guido

Réponses:

205

C'est une vieille question (2008) donc il y a beaucoup plus d'options maintenant qu'il n'y en avait alors:

MISES À JOUR (projets toujours actifs en 2020):

  • Composants Apache HTTP (4.2) Adaptateur Fluent - Remplacement de base pour JDK, utilisé par plusieurs autres candidats de cette liste. Mieux que l'ancien client HTTP Commons 3 et plus facile à utiliser pour créer votre propre client REST. Vous devrez utiliser quelque chose comme Jackson pour la prise en charge de l' analyse JSON et vous pouvez utiliser les composants HTTP URIBuilder pour construire des URI de ressources similaires au client Jersey / JAX-RS Rest. Les composants HTTP prennent également en charge NIO mais je doute que vous obtiendrez de meilleures performances que BIO étant donné la courte demande de REST. Apache HttpComponents 5 prend en charge HTTP / 2.
  • OkHttp - Remplacement de base pour JDK, similaire aux composants http, utilisé par plusieurs autres candidats de cette liste. Prend en charge les nouveaux protocoles HTTP (SPDY et HTTP2). Fonctionne sur Android. Malheureusement, il n'offre pas une véritable option asynchrone basée sur la boucle du 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).
  • Ning Async-http-client - fournit un support NIO. Anciennement appelé Async-http-client par Sonatype .
  • Feign wrapper pour les clients http de niveau inférieur (okhttp, apache httpcomponents). Crée automatiquement des clients sur la base de stubs d'interface similaires à certaines extensions Jersey et CXF. Forte intégration du ressort.
  • Retrofit - wrapper pour les clients http de niveau inférieur (okhttp). Crée automatiquement des clients sur la base de stubs d'interface similaires à certaines extensions Jersey et CXF.
  • Volley wrapper pour client jdk http, par google
  • wrapper google-http pour le client jdk http, ou apache httpcomponents, par google
  • Unirest wrapper pour jdk http client, par kong
  • Wrapper JakartaEE Resteasy pour client http jdk, par jboss, partie du framework jboss
  • wrapper jcabi-http pour apache httpcomponents, partie de la collection jcabi
  • wrapper de restlet pour apache httpcomponents, partie du cadre de restlet
  • emballage sûr avec assertions pour un test facile

Une mise en garde sur la sélection des clients HTTP / REST. Assurez-vous de vérifier ce que votre pile d'infrastructure utilise pour un client HTTP, comment elle effectue le threading et, idéalement, utilisez le même client s'il en propose un. C'est-à-dire que 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 potentiellement intéressants.

Adam Gent
la source
1
Malheureusement, le client Jersey ne prend pas en charge la méthode PATCH si elle est utilisée avec JDK <8
botchniaque
3
Unirest est très facile à utiliser mais sa conception statique le rend inutilisable dans les environnements partagés et serveurs.
bekce
9
Concernant le commentaire le moins intéressant , je voudrais ajouter qu'il semble actuellement (fin 2016) que ce projet ne soit plus maintenu. Il y a même un problème ouvert qui demande un nouveau responsable.
wegenmic
4
Pour ceux qui aiment Unirest , j'en ai une fourchette qui est actuellement activement maintenue / mise à jour.
Josh
3
serait bien de transformer la réponse en un wiki communautaire
tkruse
72

Comme je l'ai mentionné dans ce fil, j'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 JAXB / XML / JSON / Atom et ainsi de suite - afin que vous puissiez réutiliser les mêmes objets côté serveur que vous utiliser sur le test unitaire côté client.

Par exemple, voici un cas de test unitaire du projet Apache Camel qui recherche les charges utiles XML à partir d'une ressource RESTful (à l'aide de l'objet JAXB Endpoints). La méthode resource (uri) est définie dans cette classe de base qui utilise uniquement 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 le long de celle de Jersey

James Strachan
la source
Existe-t-il une méthode permettant de mentionner la liste des serveurs de service REST dans ClientResource, au cas où le serveur est en panne, essayez le serveur suivant?
Njax3SmmM2x2a0Zf7Hpd
1
Juste une mise à jour, mais pour répondre au commentaire `` BTW '' de James, la nouvelle version de JAX-RS 2.0 aura une API côté client: infoq.com/presentations/Java-REST
Nick Klauer
65

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 fichiers 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:

bdoughan
la source
15
13 lignes pour un simple appel au repos, en 2018 , cela semble beaucoup trop ...
Clint Eastwood
1
Une fois que vous ajoutez la gestion des erreurs et les options, ce n'est pas vraiment différent. Si l'approche SE semble longue, vous pouvez toujours l'envelopper dans une classe ...:> Après deux jours de débogage des conflits de bibliothèque JAX-RS, je suis très bien avec 5 lignes de code supplémentaires pour éviter tout le cauchemar SPI.
tekHedd
2
@ClintEastwood Ce message a été écrit en 2010
0ddlyoko
13

Si vous souhaitez uniquement invoquer un service REST et analyser la réponse, vous pouvez essayer Rest Assured

// 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]");
Johan
la source
J'ai trouvé cela plus élégant que la plupart des autres solutions proposées.
Herve Mutombo Il y a
9

Vous pouvez également vérifier Restlet qui a des capacités côté client complètes, 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).

Cordialement, Jerome Louvel

Jerome Louvel
la source
2
À partir du 2019-10-24, le lien a fourni des retours: `` Restlet Platform a atteint la fin de sa vie. ''
Hans Deragon
6

Vous pouvez essayer Rapa . Faites-nous part de vos commentaires à ce sujet. Et n'hésitez pas à enregistrer les problèmes ou les fonctionnalités attendues.

Jaspe
la source
1
Rapa a une interface vraiment sympa et peu de dépendances. Une bonne alternative à RestSharp dans le monde .NET.
après
projet semble mort
tkruse
6

Je voudrais souligner 2 autres options:

Ophir Radnitz
la source
1
Restfulie semble mort
tkruse
6

Essayez JdkRequestdepuis jcabi-http (je suis développeur). Voilà 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

yegor256
la source
5

J'ai récemment essayé Retrofit Library de square, c'est génial et vous pouvez appeler votre API de repos très facilement. La configuration basée sur les annotations nous permet de nous débarrasser de beaucoup de codage des plaques de chaudière.

Yasitha Waduge
la source
4

J'utilise Apache HTTPClient pour gérer tout le côté HTTP des choses.

J'écris des analyseurs XML SAX pour le contenu XML qui analyse le XML dans votre modèle d'objet. Je crois que Axis2 expose également XML -> Méthodes de modèle (Axis 1 a caché cette partie, de manière ennuyeuse). Les générateurs XML sont trivialement simples.

Il ne faut pas longtemps pour coder, et c'est assez efficace, à mon avis.

JeeBee
la source
4
À mon avis, c'est la pire façon de se reposer. La gestion manuelle de la sérialisation en Java est une perte de temps lorsque vous avez tant d'options comme JAXB et Jackson. Même le chargement de tout le document et l'utilisation de XPath sont légèrement plus lents que SAX et rien par rapport à l'obtention du XML (vitesse du réseau).
Adam Gent
1
Je suis d'accord aussi, et j'ai écrit le commentaire original. À l'époque, j'avais un désir de contrôler la désérialisation, mais de nos jours j'utiliserais des classes de modèles Jackson et décemment annotées.
JeeBee
4

OkHttp est également léger et puissant lorsqu'il est combiné avec Retrofit. Cela fonctionne bien pour une 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);
}
Sam Edwards
la source
3

Puisque personne n'a mentionné, voici un autre: Feign , qui est utilisé par Spring Cloud .

Léon
la source
2

Bien qu'il soit simple de créer un client HTTP et de faire une demande. 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 cela. 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 du code, vous pouvez trouver une bonne documentation et des réflexions sous-jacentes derrière l'outil ici .

Il y a peu d' outils WADL intéressants et utiles mentionnés sur Wintermute.

GG.
la source
1

J'ai écrit une bibliothèque qui mappe une interface java à un service JSON REST 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);
}
George Georgovassilis
la source
0

Essayez de regarder http-rest-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

À votre santé!

g00dnatur3
la source
0

Exemples de jersey Rest client:
Ajout de 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 transmettant un paramètre et obtenant une remise à jour de la liste:

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

In Above It renvoie une liste que nous acceptons en tant que liste, puis la convertissons en tableau Json puis en tableau Json en liste.

Si Post Request passe un objet Json comme 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 "));
    }
abhishek ringsia
la source
0

J'utilise actuellement https://github.com/kevinsawicki/http-request J'aime leur simplicité et la façon dont les exemples sont présentés, mais surtout j'ai été vendu quand j'ai lu:

Quelles sont les dépendances?

Aucun. Le but de cette bibliothèque est d'être une classe unique avec quelques classes statiques internes. Le projet de test nécessite Jetty pour tester les demandes par rapport à une implémentation de serveur HTTP réelle.

qui a réglé certains problèmes sur un projet java 1.6. Quant au décodage de json en objets, gson est juste invincible :)

Edoardo
la source
1
projet semble mort, aucun engagement depuis 2015.
tkruse