Chiamata RESTful in Java


150

Ho intenzione di effettuare una chiamata RESTful in Java. Tuttavia, non so come effettuare la chiamata. Devo utilizzare URLConnection o altri? Qualcuno può aiutarmi. grazie.


Dipende da come fai le chiamate di riposo nella tua applicazione. Usi un'implementazione JaxRS? Uno in particolare? Stai facendo richieste manualmente?
Colin Hebert,

@Colin Hebert, grazie per la tua risposta. Ma non ho idea della chiamata RESTful. potresti darmi maggiori informazioni sulle diverse parti della chiamata RESTful.
Domande

checkout http restful client clicca qui
Gaurav J

Risposte:


91

Se si sta chiamando un servizio RESTful da un provider di servizi (ad esempio Facebook, Twitter), lo si può fare con qualsiasi sapore di vostra scelta:

Se non si desidera utilizzare librerie esterne, è possibile utilizzare java.net.HttpURLConnectiono javax.net.ssl.HttpsURLConnection(per SSL), ma si tratta di una chiamata incapsulata in un modello di tipo Factory in java.net.URLConnection. Per ricevere il risultato, dovrai connection.getInputStream()restituire un InputStream. Dovrai quindi convertire il flusso di input in stringa e analizzare la stringa nel suo oggetto rappresentativo (ad es. XML, JSON, ecc.).

In alternativa, Apache HttpClient (la versione 4 è la più recente). È più stabile e robusto del valore predefinito di Java URLConnectione supporta la maggior parte (se non tutti) il protocollo HTTP (oltre a poter essere impostato in modalità Strict). La tua risposta sarà ancora presente InputStreame puoi usarla come indicato sopra.


Documentazione su HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html


5
Non reinventare la ruota, usa una delle implementazioni RESTful esistenti.
Qwerky,

13
Non sta reinventando la ruota, sto dicendo che puoi usare quello flavourche vuoi. Alcuni vogliono il valore predefinito URLConnection, altri vogliono HttpClient. Ad ogni modo, è lì per te da usare.
Buhake Sindi,

@ The Elite Gentleman, grazie per la tua risposta. Dopo aver controllato tutta la libreria, voglio usare Apache HttpClient, ti dispiacerebbe darmi maggiori riferimenti su questo?
Domande

@Questions, il link agli esempi di HttpClient 4 sembra essere rotto, quindi se hai qualche domanda (gioco di parole inteso ... lol), fammi sapere .... ci penso quasi quotidianamente.
Buhake Sindi,

Ti preghiamo di mostrare un codice di esempio su come usare queste classi, piuttosto che notare la loro esistenza
Jonathan,

150

Aggiornamento: sono passati quasi 5 anni da quando ho scritto la risposta di seguito; oggi ho una prospettiva diversa.

Il 99% delle volte in cui le persone usano il termine REST, significano veramente HTTP; potrebbero fregarsene di meno di "risorse", "rappresentazioni", "trasferimenti di stato", "interfacce uniformi", "ipermedia" o qualsiasi altro vincolo o aspetto dello stile dell'architettura REST identificato da Fielding . Le astrazioni fornite dai vari framework REST sono quindi confuse e inutili.

Quindi: vuoi inviare richieste HTTP usando Java nel 2015. Desideri un'API chiara, espressiva, intuitiva, idiomatica, semplice. Cosa usare? Non uso più Java, ma negli ultimi anni la libreria client HTTP Java che è sembrata la più promettente e interessante è OkHttp . Controlla.


Puoi sicuramente interagire con i servizi Web RESTful utilizzando URLConnectiono HTTPClient per codificare le richieste HTTP.

Tuttavia, è generalmente più desiderabile utilizzare una libreria o un framework che fornisca un'API più semplice e più semantica appositamente progettata per questo scopo. Ciò semplifica la scrittura, la lettura e il debug del codice e riduce la duplicazione degli sforzi. Questi framework generalmente implementano alcune grandi funzionalità che non sono necessariamente presenti o facili da usare nelle librerie di livello inferiore, come la negoziazione dei contenuti, la memorizzazione nella cache e l'autenticazione.

Alcune delle opzioni più mature sono Jersey , RESTEasy e Restlet .

Conosco molto bene Restlet e Jersey, diamo un'occhiata a come faremmo una POSTrichiesta con entrambe le API.

Esempio di maglia

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

Esempio di 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());
}

Naturalmente, le richieste GET sono ancora più semplici e puoi anche specificare cose come tag e Acceptintestazioni delle entità , ma speriamo che questi esempi siano utilmente non banali ma non troppo complessi.

Come puoi vedere, Restlet e Jersey hanno API client simili. Credo che siano stati sviluppati nello stesso periodo e quindi si siano influenzati a vicenda.

Trovo che l'API Restlet sia un po 'più semantica, e quindi un po' più chiara, ma YMMV.

Come ho detto, conosco meglio Restlet, l'ho usato in molte app per anni e ne sono molto contento. È un framework molto maturo, robusto, semplice, efficace, attivo e ben supportato. Non posso parlare con Jersey o RESTEasy, ma la mia impressione è che entrambe siano anche solide scelte.


2
Ma comunque un ottimo post. E sono d'accordo con "Il 99% delle volte in cui le persone usano il termine REST, significano davvero HTTP; ... Le astrazioni fornite da vari framework REST sono quindi confuse e inutili."
AlexD,

2
Nel tuo esempio Jersey, dove / come viene utilizzato l'oggetto Form? È stato creato, ma non sembra aggiungere nulla all'esempio.
splungebob,


24

Se hai solo bisogno di effettuare una semplice chiamata a un servizio REST da Java, usi qualcosa di simile

/*
 * 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();
    }
}

1
Ci sono alcune API REST davvero buone in circolazione, consiglierei di usarne una anziché reinventare la ruota.
Qwerky,

come ho detto: complicato da morire. (no, non ho votato a fondo questo, è una soluzione perfettamente valida)
Sean Patrick Floyd,

4
Le librerie API lato client di @Qwerky sono generalmente una violazione dei vincoli REST. Introducono troppi accoppiamenti. L'uso di una buona libreria HTTP è un'opzione molto migliore a lungo termine.
Darrel Miller,

10

Esistono diverse API RESTful in giro. Consiglierei Jersey;

https://jersey.java.net/

La documentazione dell'API client è qui;

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

La
posizione di aggiornamento per i documenti OAuth nel commento seguente è un collegamento non funzionante ed è stata spostata su https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334


6
L'OP non sta creando un'applicazione RESTful, sta effettuando chiamate RESTful, vale a dire come chiamare una risorsa del metodo API Twitter.
Buhake Sindi,

@Qwerky - Penso che sarebbe utile includere il motivo per cui raccomandi Jersey nella tua risposta.
Danny Bullis,

7

Voglio condividere la mia esperienza personale, chiamando un REST WS con una chiamata 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);
    }
}

5

Puoi dare un'occhiata al CXF . Puoi visitare l'articolo JAX-RS qui

Chiamare è semplice come questo (citazione):

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

5

In effetti, questo è "molto complicato in Java":

Da: 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();

4

La soluzione più semplice utilizzerà la libreria client http di Apache. fare riferimento al seguente codice di esempio. Questo codice utilizza la sicurezza di base per l'autenticazione.

Aggiungi la seguente dipendenza.

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


-1

È possibile utilizzare Async Http Client (la libreria supporta anche il protocollo WebSocket ) in questo modo:

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

non funziona (impossibile installare ASyncHttpClient).
Java Main,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.