Come si crea un client REST per Java? [chiuso]


248

Con JSR 311 e le sue implementazioni abbiamo un potente standard per esporre oggetti Java tramite REST. Tuttavia sul lato client sembra che manchi qualcosa che è paragonabile ad Apache Axis per SOAP, qualcosa che nasconde il servizio Web e riporta i dati in modo trasparente agli oggetti Java.

Come si creano i client Java RESTful? Usando HTTPConnection e l'analisi manuale del risultato? O clienti specializzati per esempio Jersey o Apache CXR?


Ho appena trovato Apache Wink nell'incubatrice di Apache. Potrebbe essere un progetto interessante per la creazione di server e client REST.
Yaba,


Consulta [Riposo] ( code.google.com/p/resting ). Promette di invocare i servizi REST e creare un elenco di oggetti dalla risposta XML / JSON / YAML in un solo passaggio.
Neel,

Il riposo ha problemi con le richieste POST.
RyanBrady,

2
Puoi farlo in modo molto semplice con resteasy (di Jboss). Ho scritto un post sul blog su come sviluppare un client REST Java se si desidera una guida introduttiva. Comunque, ci sono centinaia di alternative in Java.
Guido,

Risposte:


205

Questa è una vecchia domanda (2008), quindi ora ci sono molte più opzioni di quante ce ne fossero allora:

AGGIORNAMENTI (progetti ancora attivi nel 2020):

  • Apache HTTP Components (4.2) Adattatore fluido - Sostituzione di base per JDK, utilizzata da molti altri candidati in questo elenco. Meglio del vecchio client HTTP Commons 3 e più facile da usare per costruire il proprio client REST. Dovrai utilizzare qualcosa come Jackson per il supporto dell'analisi JSON e puoi utilizzare i componenti HTTP URIBuilder per costruire URI di risorse simili al client Rest Jersey / JAX-RS. Anche i componenti HTTP supportano NIO, ma dubito che otterrai prestazioni migliori rispetto a BIO data la breve richiesta di REST. Apache HttpComponents 5 ha il supporto HTTP / 2.
  • OkHttp - Sostituzione di base per JDK, simile ai componenti http, utilizzata da molti altri candidati in questo elenco. Supporta protocolli HTTP più recenti (SPDY e HTTP2). Funziona su Android. Sfortunatamente non offre una vera opzione asincrona basata su un reattore (vedi sopra i componenti Ning e HTTP). Tuttavia, se si utilizza il protocollo HTTP2 più recente, ciò rappresenta un problema minore (presupponendo che il conteggio delle connessioni sia un problema).
  • Ning Async-http-client : fornisce supporto NIO. Precedentemente noto come Async-http-client da Sonatype .
  • Wrapper per client http di livello inferiore (okhttp, apache httpcomponents). Crea automaticamente client basati su stub di interfaccia simili ad alcune estensioni Jersey e CXF. Forte integrazione primaverile.
  • Retrofit - wrapper per client http di livello inferiore (okhttp). Crea automaticamente client basati su stub di interfaccia simili ad alcune estensioni Jersey e CXF.
  • Volley wrapper per JDK http cliente, da parte di Google
  • wrapper google-http per client http jdk o apache httpcomponents, da google
  • Unirest wrapper per client http jdk, di kong
  • Wrapper resteasy JakartaEE per client http jdk, di jboss, parte del framework jboss
  • wrapper jcabi-http per i componenti http di apache, parte della raccolta jcabi
  • wrapper restlet per i componenti http di apache, parte del framework restlet
  • involucro sicuro con affermazioni per un facile test

Un avvertimento sulla scelta dei client HTTP / REST. Assicurati di controllare cosa sta usando il tuo stack di framework per un client HTTP, come funziona il threading e usa idealmente lo stesso client se ne offre uno. Cioè se stai usando qualcosa come Vert.x o Play potresti voler provare a usare il suo client di supporto per partecipare a qualsiasi circuito bus o di reattore fornito dal framework ... altrimenti preparati a problemi di thread probabilmente interessanti.


1
Sfortunatamente il client Jersey non supporta il metodo PATCH se utilizzato con JDK <8
botchniaque il

3
Unirest è molto facile da usare ma il suo design statico lo rende inutilizzabile in ambienti condivisi e server.
Bekce,

9
Per quanto riguarda il commento più irreale , vorrei aggiungere che attualmente (fine 2016) sembra che questo progetto non sia più mantenuto. C'è anche un problema aperto che richiede un nuovo manutentore.
wegenmic,

4
Per coloro a cui piace Unirest , ne ho un fork che è attualmente attivamente mantenuto / aggiornato.
Josh,

3
sarebbe bello trasformare la risposta in un wiki della comunità
tkruse il

72

Come ho già detto in questa discussione, tendo ad usare Jersey che implementa JAX-RS e viene fornito con un bel client REST. La cosa bella è che se si implementano le risorse RESTful utilizzando JAX-RS, il client Jersey può riutilizzare i provider di entità come JAXB / XML / JSON / Atom e così via, in modo da poter riutilizzare gli stessi oggetti sul lato server utilizzare nel test dell'unità lato client.

Ad esempio, ecco un caso di test unitario del progetto Apache Camel che cerca i payload XML da una risorsa RESTful (usando l'oggetto JAXB Endpoint). Il metodo di risorsa (uri) è definito in questa classe di base che utilizza solo l'API client Jersey.

per esempio

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

A proposito, spero che la futura versione di JAX-RS aggiunga una bella API lato client sulla falsariga di quella in Jersey


Esiste un metodo in cui è possibile menzionare l'elenco dei server del servizio REST in ClientResource, nel caso in cui il server non sia attivo, provare il server successivo?
Njax3SmmM2x2a0Zf7Hpd

1
Solo un aggiornamento, ma per rispondere al commento di James "BTW", la nuova versione di JAX-RS 2.0 avrà un'API lato client: infoq.com/presentations/Java-REST
Nick Klauer,

65

È possibile utilizzare le 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); 
    } 
} 

In alternativa, è possibile utilizzare le API client REST fornite dalle implementazioni JAX-RS come Jersey. Queste API sono più facili da usare, ma richiedono barattoli aggiuntivi sul percorso della 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); 

Per ulteriori informazioni, vedere:


15
13 linee per una semplice chiamata di riposo, nel 2018 , sembra troppo ...
Clint Eastwood,

1
Dopo aver aggiunto la gestione degli errori e le opzioni, non è molto diverso. Se l'approccio SE sembra lungo, puoi sempre inserirlo in una classe ...:> Dopo due giorni di debug dei conflitti nella libreria JAX-RS sto davvero bene con 5 righe di codice extra per evitare l'intero incubo SPI.
tekHedd

2
@ClintEastwood questo post è stato scritto nel 2010
0ddlyoko il

13

Se desideri solo invocare un servizio REST e analizzare la risposta, puoi provare 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]");

Ho trovato questo più elegante di molte altre soluzioni proposte.
Herve Mutombo,

9

Puoi anche controllare Restlet che ha funzionalità complete sul lato client, più orientate al REST rispetto alle librerie di livello inferiore come HttpURLConnection o Apache HTTP Client (che possiamo sfruttare come connettori).

Cordiali saluti, Jerome Louvel


2
A partire dal 24-10-2019, il link fornito restituisce: "La piattaforma Restlet ha raggiunto la fine della vita".
Hans Deragon,

6

Potresti provare Rapa . Facci sapere il tuo feedback sullo stesso. E sentiti libero di registrare problemi o funzionalità previste.


1
Rapa ha un'interfaccia davvero carina e poche dipendenze. Una buona alternativa a RestSharp nel mondo .NET.
pomeriggio

il progetto sembra morto
tkruse il



5

Di recente ho provato Retrofit Library da Square, è fantastico e puoi chiamare l'API di riposo molto facilmente. La configurazione basata su annotazioni ci consente di eliminare molta codifica della piastra della caldaia.


4

Uso Apache HTTPClient per gestire tutto il lato HTTP delle cose.

Scrivo parser XML SAX per il contenuto XML che analizza l'XML nel modello a oggetti. Credo che Axis2 esponga anche i metodi XML -> Model (l'Asse 1 ha nascosto questa parte, in modo fastidioso). I generatori XML sono banalmente semplici.

Non ci vuole molto a programmare, ed è abbastanza efficiente, secondo me.


4
Secondo me questo è il modo peggiore per fare il RESTO. La gestione manuale della serializzazione in Java è una perdita di tempo quando si hanno così tante opzioni come JAXB e Jackson. Anche caricare l'intero documento e utilizzare XPath è leggermente più lento di SAX e nulla rispetto all'ottenimento dell'XML (velocità della rete).
Adam Gent,

1
Anch'io sono d'accordo e ho scritto il commento originale. All'epoca avevo il desiderio di controllare la deserializzazione, ma oggigiorno avrei usato Jackson e classi di modelli con annotazioni decenti.
JeeBee,

4

OkHttp è leggero e potente se combinato anche con Retrofit. Funziona bene per l'uso generale di Java e su 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();
}

Retrofit : http://square.github.io/retrofit/

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


2

Anche se è semplice creare un client HTTP e fare un test. Ma se si desidera utilizzare alcuni client generati automaticamente, è possibile utilizzare WADL per descrivere e generare codice.

Puoi usare RestDescribe per generare e compilare WSDL, puoi generare client in php, ruby, python, java e C # usando questo. Genera codice pulito e c'è un buon cambiamento che devi modificare un po 'dopo la generazione del codice, puoi trovare una buona documentazione e pensieri sottostanti dietro lo strumento qui .

Ci sono alcuni strumenti WADL interessanti e utili menzionati su wintermute.




0

Prova a guardare http-rest-client

https://github.com/g00dnatur3/http-rest-client

Qui c'è un semplice esempio:

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 libreria si occupa della serializzazione e dell'associazione json per te.

Ecco un altro esempio,

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

E un ultimo esempio,

RestClient client = RestClient.builder().build();
String url = ...
Person person = client.get(url, null, Person.class); //no queryParams

Saluti!


0

Esempi di jersey Rest client:
Aggiunta di dipendenza:

         <!-- 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 e passando due parametri:

          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 passando un parametro e ottenendo un respone dell'elenco:

       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 Restituisce un Elenco che stiamo accettando come Elenco e quindi convertendolo in Json Array e quindi Json Array in Elenco.

Se la richiesta di post passa l'oggetto Json come parametro:

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

0

Attualmente sto usando https://github.com/kevinsawicki/http-request Mi piace la loro semplicità e il modo in cui vengono mostrati gli esempi, ma principalmente sono stato venduto quando ho letto:

Quali sono le dipendenze?

Nessuna. L'obiettivo di questa libreria è di essere una singola classe con alcune classi statiche interne. Il progetto di test richiede Jetty per testare le richieste rispetto a un'implementazione effettiva del server HTTP.

che risolveva alcuni problemi su un progetto java 1.6. Per quanto riguarda la decodifica di json in oggetti, gson è semplicemente invincibile :)


1
il progetto sembra morto, nessun
impegno
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.