web-dev-qa-db-fra.com

REST clients pour Java?

Avec JSR 311 et ses implémentations, nous avons un standard puissant pour exposer les objets Java via REST. Cependant, du côté client, il semble qu'il manque quelque chose de comparable à Apache Axis pour SOAP - quelque chose qui masque le service Web et regroupe les données de manière transparente en objets Java.

Comment créez-vous Java clients RESTful? Utilisation de HTTPConnection et analyse manuelle du résultat? Ou des clients spécialisés, par exemple Jersey ou Apache CXR?

220
Yaba

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 différentes
  • Jersey (mentionné ci-dessus).
  • Spring a aussi son propre appelé RestTemplate
  • Client HTTP Commons construisez le vôtre pour d'anciens projets Java.

MISE À JOUR vers 2014:

Le nouveau venu qui fournit le support NIO (même si, à vrai dire, je ne pense pas que cela améliore réellement les performances des clients, contrairement aux serveurs).

MISE À JOUR 2016 :

  • OkHttp - Prend en charge les nouveaux protocoles HTTP (SPDY et HTTP2). Fonctionne sur Android. Malheureusement, il ne propose pas une véritable option async basée sur la boucle du réacteur (voir Composants Ning et HTTP ci-dessus). Toutefois, si vous utilisez le protocole HTTP2 plus récent, le problème est moins grave (en supposant que le nombre de connexions est un problème).
  • Retrofit - Crée automatiquement des clients sur la base de talons d'interface similaires à certaines extensions Jersey et CXF. Utilise OkHttp.
  • Apache HttpComponents 5 aurait soi-disant le support de HTTP2

Une mise en garde sur le choix des clients HTTP/REST. Assurez-vous de vérifier l'utilisation de votre pile d'infrastructure pour un client HTTP, son mode de threading et, idéalement, d'utiliser 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 utiliser son client de support pour participer à la boucle de bus ou de réacteur fournie par la structure ... sinon, préparez-vous à des problèmes de threads potentiellement intéressants.

181
Adam Gent

Comme je l'ai mentionné dans ce fil , j'ai tendance à utiliser Jersey qui implémente JAX-RS et est livré avec un client Nice REST. La bonne chose est que si vous implémentez vos ressources RESTful avec JAX-RS, le client Jersey peut réutiliser les fournisseurs d’entités tels que JAXB/XML/JSON/Atom et ainsi de suite - vous pouvez ainsi réutiliser les mêmes objets côté serveur que vous-même. utiliser sur le test unitaire côté client.

Par exemple, voici un cas de test unitaire du projet Apache Camel qui recherche les charges 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 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);        

En passant, j'espère que la future version de JAX-RS ajoutera une API côté client Nice, semblable à celle de Jersey.

70
James Strachan

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

Vous pouvez également 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:

61
bdoughan

Si vous souhaitez uniquement appeler 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]");
11
Johan

Vous pouvez également vérifier Restlet qui dispose de toutes les fonctionnalités 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 utiliser comme connecteurs).

Cordialement, Jérôme Louvel

10
Jerome Louvel

J'ai récemment essayé Retrofit Bibliothèque 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 supprimer beaucoup de codage de la plaque de la chaudière.

7

Vous pouvez essayer Rapa . Faites-nous savoir vos commentaires à propos de la même chose. Et n'hésitez pas à consigner les problèmes ou les fonctionnalités attendues.

7
HariKrishnan

Je voudrais souligner 2 autres options:

6
Ophir Radnitz

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 les méthodes XML -> Model (l’axe 1 a caché cette partie, ennuyeux). Les générateurs XML sont trivialement simples.

Il ne faut pas longtemps pour coder et est très efficace, à mon avis.

5
JeeBee

OkHttp est léger et puissant lorsqu'il est associé à Retrofit. Cela fonctionne bien pour Java général 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étrofit : http://square.github.io/retrofit/

public interface GitHubService {
  @GET("/users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}
5
Sam Edwards

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

4
Leon

Essayez JdkRequest de jcabi-http (je suis un développeur). Voilà comment cela fonctionne:

String body = new JdkRequest("http://www.google.com")
  .header("User-Agent", "it's me")
  .fetch()
  .body()

Consultez ce billet de blog pour plus de détails: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

4
yegor256

Depuis quelque temps, j'utilise Resty :

JSONResource jsonResource = new Resty().json(uri);

On peut trouver quelques exemples ici .

2
aribeiro

Exemples de client Reste jersey:
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 en passant un paramètre et en obtenant une réponse de 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 et que nous convertissons ensuite en Json Array, puis en Json Array en liste.

Si Post Request transmet l'objet Json en tant que 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 "));
    }
1
abhishek ringsia

Bien que sa simple pour créer un client HTTP et faire une recette. 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 également générer des clients en php, Ruby, python, Java et C #. Il génère du code propre et il y a un bon changement. Vous devez le modifier un peu après la génération du code. Vous pouvez trouver une bonne documentation et les idées sous-jacentes derrière l'outil ici .

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

1
GG.

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 prend en charge la sérialisation json et la liaison 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é!

1
g00dnatur3

J'ai écrit une bibliothèque qui mappe une interface Java sur 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);
}
1