RESTful Aufruf in Java

150

Ich werde einen RESTful-Anruf in Java tätigen. Ich weiß jedoch nicht, wie ich den Anruf tätigen soll. Muss ich die URLConnection oder andere verwenden? Kann mir jemand helfen. Danke.

Fragen
quelle
Dies hängt davon ab, wie Sie in Ihrer Anwendung Ruhegespräche führen. Verwenden Sie eine JaxRS-Implementierung? Ein bestimmter? Führen Sie Anfragen manuell durch?
Colin Hebert
@Colin Hebert, danke für deine Antwort. Aber ich habe keine Ahnung von dem RESTful-Aufruf. Können Sie mir weitere Informationen zu verschiedenen Teilen des RESTful-Aufrufs geben?
Fragen
Kasse http erholsamer Client hier klicken
Gaurav J

Antworten:

91

Wenn Sie einen RESTful-Dienst von einem Dienstanbieter (z. B. Facebook, Twitter) anrufen, können Sie dies mit einer beliebigen Variante Ihrer Wahl tun :

Wenn Sie keine externen Bibliotheken verwenden möchten, können Sie java.net.HttpURLConnectionoder javax.net.ssl.HttpsURLConnection(für SSL) verwenden. Dies ist jedoch ein Aufruf, der in einem Factory-Typmuster in gekapselt ist java.net.URLConnection. Um das Ergebnis zu erhalten, müssen connection.getInputStream()Sie eine zurückgeben InputStream. Anschließend müssen Sie Ihren Eingabestream in eine Zeichenfolge konvertieren und die Zeichenfolge in das repräsentative Objekt (z. B. XML, JSON usw.) analysieren.

Alternativ Apache HttpClient (Version 4 ist die neueste). Es ist stabiler und robuster als die Standardeinstellung von Java URLConnectionund unterstützt die meisten (wenn nicht alle) HTTP-Protokolle (und kann auch auf den strengen Modus eingestellt werden). Ihre Antwort bleibt erhalten InputStreamund Sie können sie wie oben erwähnt verwenden.


Dokumentation zu HttpClient: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/index.html

Buhake Sindi
quelle
5
Erfinden Sie das Rad nicht neu, verwenden Sie eine der vorhandenen RESTful-Implementierungen.
Qwerky
13
Es ist nicht neu zu erfinden, ich sage, Sie können verwenden, was flavourSie wollen. Einige wollen die Standardeinstellung URLConnection, andere wollen HttpClient. In jedem Fall steht es Ihnen zur Verfügung.
Buhake Sindi
@ The Elite Gentleman, vielen Dank für Ihre Antwort. Nachdem ich die gesamte Bibliothek überprüft habe, möchte ich den Apache HttpClient verwenden. Würde es Ihnen etwas ausmachen, mir weitere Informationen zu dieser Bibliothek zu geben?
Fragen
@Fragen, der Link zu den HttpClient 4-Beispielen scheint unterbrochen zu sein. Wenn Sie also Fragen haben (Wortspiel beabsichtigt ... lol), lassen Sie es mich wissen ... Ich beschäftige mich fast täglich damit.
Buhake Sindi
Bitte zeigen Sie einen Beispielcode für die Verwendung dieser Klassen, anstatt nur ihre Existenz zu notieren
Jonathan
150

Update: Es ist fast 5 Jahre her, seit ich die Antwort unten geschrieben habe; Heute habe ich eine andere Perspektive.

In 99% der Fälle, in denen Menschen den Begriff REST verwenden, meinen sie wirklich HTTP. Sie könnten sich weniger um „Ressourcen“, „Darstellungen“, „Statusübertragungen“, „einheitliche Schnittstellen“, „Hypermedien“ oder andere Einschränkungen oder Aspekte des von Fielding identifizierten REST-Architekturstils kümmern . Die von verschiedenen REST-Frameworks bereitgestellten Abstraktionen sind daher verwirrend und nicht hilfreich.

Also: Sie möchten 2015 HTTP-Anfragen mit Java senden. Sie möchten eine API, die klar, ausdrucksstark, intuitiv, idiomatisch und einfach ist. Was ist zu verwenden? Ich verwende kein Java mehr, aber in den letzten Jahren war OkHttp die vielversprechendste und interessanteste Java-HTTP-Client-Bibliothek . Hör zu.


Sie können definitiv mit RESTful-Webdiensten interagieren, indem Sie URLConnectionoder HTTPClient verwenden, um HTTP-Anforderungen zu codieren.

Im Allgemeinen ist es jedoch wünschenswerter, eine Bibliothek oder ein Framework zu verwenden, das eine einfachere und semantischere API bietet, die speziell für diesen Zweck entwickelt wurde. Dies erleichtert das Schreiben, Lesen und Debuggen des Codes und reduziert Doppelarbeit. Diese Frameworks implementieren im Allgemeinen einige großartige Funktionen, die in Bibliotheken niedrigerer Ebenen nicht unbedingt vorhanden oder einfach zu verwenden sind, z. B. Inhaltsverhandlung, Caching und Authentifizierung.

Einige der ausgereiftesten Optionen sind Jersey , RESTEasy und Restlet .

Ich bin mit Restlet und Jersey am besten vertraut. Schauen wir uns an, wie wir POSTmit beiden APIs eine Anfrage stellen würden.

Jersey Beispiel

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

Restlet-Beispiel

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

Natürlich sind GET-Anforderungen noch einfacher, und Sie können auch Dinge wie Entitäts-Tags und Accept-Header angeben , aber hoffentlich sind diese Beispiele nicht trivial, aber nicht zu komplex.

Wie Sie sehen können, haben Restlet und Jersey ähnliche Client-APIs. Ich glaube, sie wurden ungefähr zur gleichen Zeit entwickelt und haben sich daher gegenseitig beeinflusst.

Ich finde die Restlet-API etwas semantischer und daher etwas klarer, aber YMMV.

Wie gesagt, ich bin mit Restlet am besten vertraut, ich habe es jahrelang in vielen Apps verwendet und bin sehr zufrieden damit. Es ist ein sehr ausgereiftes, robustes, einfaches, effektives, aktives und gut unterstütztes Framework. Ich kann nicht mit Jersey oder RESTEasy sprechen, aber ich habe den Eindruck, dass beide auch eine gute Wahl sind.

Avi Flachs
quelle
2
Aber immer noch ein toller Beitrag. Und ich muss zustimmen, dass "99% der Zeit, in der Menschen den Begriff REST verwenden, wirklich HTTP bedeuten; ... Die Abstraktionen, die von verschiedenen REST-Frameworks bereitgestellt werden, sind daher verwirrend und nicht hilfreich."
AlexD
2
Wo / wie wird in Ihrem Jersey-Beispiel das Formularobjekt verwendet? Es wurde erstellt, aber es scheint dem Beispiel nichts hinzuzufügen.
Splungebob
24

Wenn Sie nur einen einfachen Aufruf eines REST-Dienstes von Java aus benötigen, verwenden Sie etwas in dieser Richtung

/*
 * 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();
    }
}
Jitter
quelle
1
Es gibt einige wirklich gute REST-APIs. Ich würde empfehlen, eine zu verwenden, anstatt das Rad neu zu erfinden.
Qwerky
wie gesagt: höllisch kompliziert. (Nein, ich habe dies nicht abgelehnt, es ist eine absolut gültige Lösung)
Sean Patrick Floyd
4
@Qwerky Client-seitige API-Bibliotheken verstoßen normalerweise gegen REST-Einschränkungen. Sie führen viel zu viel Kopplung ein. Die Verwendung einer guten HTTP-Bibliothek ist auf lange Sicht eine viel bessere Option.
Darrel Miller
10

Es gibt mehrere RESTful-APIs. Ich würde Jersey empfehlen;

https://jersey.java.net/

Die Client-API-Dokumentation finden Sie hier.

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

Der Speicherort
für die OAuth-Dokumente im Kommentar unten ist ein toter Link und wurde zu https://jersey.java.net/nonav/documentation/latest/security.html#d0e12334 verschoben

Qwerky
quelle
6
Das OP erstellt keine RESTful-Anwendung, sondern führt RESTful-Aufrufe durch, z. B. das Aufrufen einer Twitter-API-Methodenressource.
Buhake Sindi
@Qwerky - Ich denke, es wäre hilfreich, in Ihrer Antwort anzugeben, warum Sie Jersey empfehlen.
Danny Bullis
7

Ich möchte meine persönlichen Erfahrungen mit dem Aufruf eines REST-WS mit einem Post-JSON-Aufruf teilen:

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
quelle
5

Sie können den CXF auschecken . Den JAX-RS-Artikel finden Sie hier

So einfach ist das Anrufen (Zitat):

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
quelle
5

In der Tat ist dies "in Java sehr kompliziert":

Von: 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
quelle
4

Die einfachste Lösung wird die Apache http-Client-Bibliothek verwenden. Siehe folgenden Beispielcode. Dieser Code verwendet die grundlegende Sicherheit für die Authentifizierung.

Fügen Sie die folgende Abhängigkeit hinzu.

<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
quelle
-1

Sie können den Async Http Client (die Bibliothek unterstützt auch das WebSocket- Protokoll) folgendermaßen verwenden:

    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
quelle
es funktioniert nicht (kann ASyncHttpClient nicht instanziieren).
Java Main