Appel RESTful en Java

150

Je vais passer un appel RESTful en Java. Cependant, je ne sais pas comment passer l'appel. Dois-je utiliser URLConnection ou autres? Quelqu'un peut-il m'aider. Merci.

Des questions
la source
Cela dépend de la façon dont vous restez les appels dans votre application. Utilisez-vous une implémentation JaxRS? Un en particulier? Faites-vous des demandes manuellement?
Colin Hebert
@Colin Hebert, merci pour votre réponse. Mais je n'ai aucune idée de l'appel RESTful. pourriez-vous me donner plus d'informations sur les différentes parties de l'appel RESTful.
Questions du
checkout http client reposant cliquez ici
Gaurav J

Réponses:

91

Si vous appelez un service RESTful à partir d'un fournisseur de services (par exemple Facebook, Twitter), vous pouvez le faire avec n'importe quelle saveur de votre choix:

Si vous ne souhaitez pas utiliser de bibliothèques externes, vous pouvez utiliser java.net.HttpURLConnectionou javax.net.ssl.HttpsURLConnection(pour SSL), mais cet appel est encapsulé dans un modèle de type Factory dans java.net.URLConnection. Pour recevoir le résultat, vous devrez à connection.getInputStream()quel retour vous un InputStream. Vous devrez ensuite convertir votre flux d'entrée en chaîne et analyser la chaîne en son objet représentatif (par exemple XML, JSON, etc.).

Alternativement, Apache HttpClient (la version 4 est la dernière). Il est plus stable et robuste que la valeur par défaut de java URLConnectionet il prend en charge la plupart (sinon la totalité) du protocole HTTP (ainsi qu'il peut être défini en mode strict). Votre réponse sera toujours en cours InputStreamet vous pourrez l'utiliser comme indiqué ci-dessus.


Documentation sur HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html

Buhake Sindi
la source
5
Ne réinventez pas la roue, utilisez l'une des implémentations RESTful existantes.
Qwerky
13
Il ne s'agit pas de réinventer la roue, je dis que vous pouvez utiliser ce que flavourvous voulez. Certains veulent la valeur par défaut URLConnection, d'autres veulent HttpClient. Dans tous les cas, vous pouvez l'utiliser.
Buhake Sindi
@The Elite Gentleman, merci pour votre réponse. Après avoir vérifié l'ensemble de la bibliothèque, je souhaite utiliser Apache HttpClient, pourriez-vous me donner plus de références à propos de celui-ci?
Questions du
@Questions, le lien vers les exemples HttpClient 4 semble être rompu, donc si vous avez des questions (jeu de mots ... lol), faites-le moi savoir .... Je m'en occupe presque quotidiennement.
Buhake Sindi
Veuillez montrer un exemple de code sur la façon d'utiliser ces classes, plutôt que de simplement noter leur existence
Jonathan
150

Mise à jour: Cela fait presque 5 ans que j'ai écrit la réponse ci-dessous; aujourd'hui, j'ai une perspective différente.

99% du temps, quand les gens utilisent le terme REST, ils veulent vraiment dire HTTP; ils ne se soucient guère des «ressources», des «représentations», des «transferts d'état», des «interfaces uniformes», de «l'hypermédia» ou de toute autre contrainte ou aspect du style d'architecture REST identifié par Fielding . Les abstractions fournies par divers frameworks REST sont donc déroutantes et inutiles.

Donc: vous voulez envoyer des requêtes HTTP en Java en 2015. Vous voulez une API claire, expressive, intuitive, idiomatique, simple. Quoi utiliser? Je n'utilise plus Java, mais depuis quelques années la bibliothèque client HTTP Java qui me paraissait la plus prometteuse et la plus intéressante est OkHttp . Vérifiez-le.


Vous pouvez certainement interagir avec les services Web RESTful en utilisant URLConnectionou HTTPClient pour coder les requêtes HTTP.

Cependant, il est généralement plus souhaitable d'utiliser une bibliothèque ou un framework qui fournit une API plus simple et plus sémantique spécialement conçue à cet effet. Cela facilite l'écriture, la lecture et le débogage du code et réduit la duplication des efforts. Ces frameworks implémentent généralement des fonctionnalités intéressantes qui ne sont pas nécessairement présentes ou faciles à utiliser dans les bibliothèques de niveau inférieur, telles que la négociation de contenu, la mise en cache et l'authentification.

Certaines des options les plus matures sont Jersey , RESTEasy et Restlet .

Je connais le mieux Restlet et Jersey, voyons comment nous pourrions faire une POSTdemande avec les deux API.

Exemple de maillot

Form form = new Form();
form.add("x", "foo");
form.add("y", "bar");

Client client = ClientBuilder.newClient();

WebTarget resource = client.target("http://localhost:8080/someresource");

Builder request = resource.request();
request.accept(MediaType.APPLICATION_JSON);

Response response = request.get();

if (response.getStatusInfo().getFamily() == Family.SUCCESSFUL) {
    System.out.println("Success! " + response.getStatus());
    System.out.println(response.getEntity());
} else {
    System.out.println("ERROR! " + response.getStatus());    
    System.out.println(response.getEntity());
}

Exemple de restlet

Form form = new Form();
form.add("x", "foo");
form.add("y", "bar");

ClientResource resource = new ClientResource("http://localhost:8080/someresource");

Response response = resource.post(form.getWebRepresentation());

if (response.getStatus().isSuccess()) {
    System.out.println("Success! " + response.getStatus());
    System.out.println(response.getEntity().getText());
} else {
    System.out.println("ERROR! " + response.getStatus());
    System.out.println(response.getEntity().getText());
}

Bien sûr, les requêtes GET sont encore plus simples et vous pouvez également spécifier des éléments tels que des balises d'entité et des en- Accepttêtes, mais j'espère que ces exemples sont utilement non triviaux mais pas trop complexes.

Comme vous pouvez le voir, Restlet et Jersey ont des API client similaires. Je pense qu'ils ont été développés à peu près à la même époque et qu'ils se sont donc influencés.

Je trouve que l'API Restlet est un peu plus sémantique, et donc un peu plus claire, mais YMMV.

Comme je l'ai dit, je suis plus familier avec Restlet, je l'ai utilisé dans de nombreuses applications pendant des années et j'en suis très satisfait. C'est un framework très mature, robuste, simple, efficace, actif et bien pris en charge. Je ne peux pas parler de Jersey ou de RESTEasy, mais j'ai l'impression que ce sont tous les deux des choix solides.

Lin Avi
la source
2
Mais toujours un excellent post. Et je suis d'accord avec "99% du temps, quand les gens utilisent le terme REST, ils veulent vraiment dire HTTP; ... Les abstractions fournies par divers frameworks REST sont donc déroutantes et inutiles."
AlexD
2
Dans votre exemple Jersey, où / comment l'objet Form est-il utilisé? Il est créé, mais il ne semble rien ajouter à l'exemple.
splungebob
24

Si vous avez juste besoin de faire un simple appel à un service REST depuis java, vous utilisez quelque chose de ce genre

/*
 * Stolen from http://xml.nig.ac.jp/tutorial/rest/index.html
 * and http://www.dr-chuck.com/csev-blog/2007/09/calling-rest-web-services-from-java/
*/
import java.io.*;
import java.net.*;

public class Rest {

    public static void main(String[] args) throws IOException {
        URL url = new URL(INSERT_HERE_YOUR_URL);
        String query = INSERT_HERE_YOUR_URL_PARAMETERS;

        //make connection
        URLConnection urlc = url.openConnection();

        //use post mode
        urlc.setDoOutput(true);
        urlc.setAllowUserInteraction(false);

        //send query
        PrintStream ps = new PrintStream(urlc.getOutputStream());
        ps.print(query);
        ps.close();

        //get result
        BufferedReader br = new BufferedReader(new InputStreamReader(urlc
            .getInputStream()));
        String l = null;
        while ((l=br.readLine())!=null) {
            System.out.println(l);
        }
        br.close();
    }
}
trembler
la source
1
Il existe de très bonnes API REST, je recommanderais d'en utiliser une plutôt que de réinventer la roue.
Qwerky
comme je l'ai dit: compliqué comme l'enfer. (non, je n'ai pas voté contre cela, c'est une solution parfaitement valable)
Sean Patrick Floyd
4
Les bibliothèques d'API côté client @Qwerky constituent généralement une violation des contraintes REST. Ils introduisent beaucoup trop de couplage. Utiliser une bonne bibliothèque HTTP est une bien meilleure option à long terme.
Darrel Miller
10

Il existe plusieurs API RESTful. Je recommanderais Jersey;

https://jersey.java.net/

La documentation de l'API client est ici;

https://jersey.java.net/documentation/latest/index.html

L'
emplacement de mise à jour des documents OAuth dans le commentaire ci-dessous est un lien mort et a été déplacé vers https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334

Qwerky
la source
6
L'OP ne crée pas une application RESTful, il effectue des appels RESTful, c'est-à-dire comme appeler une ressource de méthode API Twitter.
Buhake Sindi
@Qwerky - Je pense qu'il serait utile d'indiquer pourquoi vous recommandez Jersey dans votre réponse.
Danny Bullis
7

Je souhaite partager mon expérience personnelle en appelant un WS REST avec un appel Post JSON:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;

public class HWS {

    public static void main(String[] args) throws IOException {
        URL url = new URL("INSERT YOUR SERVER REQUEST");
        //Insert your JSON query request
        String query = "{'PARAM1': 'VALUE','PARAM2': 'VALUE','PARAM3': 'VALUE','PARAM4': 'VALUE'}";
        //It change the apostrophe char to double colon char, to form a correct JSON string
        query=query.replace("'", "\"");

        try{
            //make connection
            URLConnection urlc = url.openConnection();
            //It Content Type is so importan to support JSON call
            urlc.setRequestProperty("Content-Type", "application/xml");
            Msj("Conectando: " + url.toString());
            //use post mode
            urlc.setDoOutput(true);
            urlc.setAllowUserInteraction(false);

            //send query
            PrintStream ps = new PrintStream(urlc.getOutputStream());
            ps.print(query);
            Msj("Consulta: " + query);
            ps.close();

            //get result
            BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
            String l = null;
            while ((l=br.readLine())!=null) {
                Msj(l);
            }
            br.close();
        } catch (Exception e){
            Msj("Error ocurrido");
            Msj(e.toString());
        }
    }

    private static void Msj(String texto){
        System.out.println(texto);
    }
}
Lisandro
la source
5

Vous pouvez consulter le CXF . Vous pouvez visiter l'article JAX-RS ici

L'appel est aussi simple que cela (citation):

BookStore store = JAXRSClientFactory.create("http://bookstore.com", BookStore.class);
// (1) remote GET call to http://bookstore.com/bookstore
Books books = store.getAllBooks();
// (2) no remote call
BookResource subresource = store.getBookSubresource(1);
// {3} remote GET call to http://bookstore.com/bookstore/1
Book b = subresource.getDescription();
Joopiter
la source
5

En effet, c'est "très compliqué en Java":

De: https://jersey.java.net/documentation/latest/client.html

Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo").path("bar");
Invocation.Builder invocationBuilder = target.request(MediaType.TEXT_PLAIN_TYPE);
Response response = invocationBuilder.get();
JRun
la source
4

La solution la plus simple utilisera la bibliothèque cliente Apache http. reportez-vous à l'exemple de code suivant .. ce code utilise la sécurité de base pour l'authentification.

Ajoutez la dépendance suivante.

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4</version>
</dependency>
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
Credentials credentials = new UsernamePasswordCredentials("username", "password");
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build();
HttpPost request = new HttpPost("https://api.plivo.com/v1/Account/MAYNJ3OT/Message/");HttpResponse response = client.execute(request);
    // Get the response
    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    String line = "";
    while ((line = rd.readLine()) != null) {    
    textView = textView + line;
    }
    System.out.println(textView);
Hemin
la source
1

Je vois de nombreuses réponses, voici ce que nous utilisons dans WebClient 2020 , et BTW RestTemplate va devenir obsolète. (peut vérifier cela) RestTemplate va être obsolète

Francis Raj
la source
Au lieu de fournir un lien, pouvez-vous s'il vous plaît ajouter une explication ici?
Kishan Bharda le
-1

Vous pouvez utiliser Async Http Client (la bibliothèque prend également en charge le protocole WebSocket ) comme ça:

    String clientChannel = UriBuilder.fromPath("http://localhost:8080/api/{id}").build(id).toString();

    try (AsyncHttpClient asyncHttpClient = new AsyncHttpClient())
    {
        BoundRequestBuilder postRequest = asyncHttpClient.preparePost(clientChannel);
        postRequest.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
        postRequest.setBody(message.toString()); // returns JSON
        postRequest.execute().get();
    }
kayz1
la source
cela ne fonctionne pas (ne peut pas instancier ASyncHttpClient).
Java Main