Wie erstellt man einen REST-Client für Java? [geschlossen]

247

Mit JSR 311 und seinen Implementierungen haben wir einen leistungsstarken Standard für die Bereitstellung von Java-Objekten über REST. Auf der Clientseite scheint jedoch etwas zu fehlen, das mit Apache Axis for SOAP vergleichbar ist - etwas, das den Webdienst verbirgt und die Daten transparent auf Java-Objekte zurückführt.

Wie erstellen Sie Java RESTful-Clients? Verwenden Sie HTTPConnection und manuelles Parsen des Ergebnisses? Oder spezialisierte Kunden für zB Jersey oder Apache CXR?

Yaba
quelle
Ich habe gerade Apache Wink im Apache Incubator gefunden. Könnte ein interessantes Projekt zum Erstellen von REST-Servern und -Clients sein.
Yaba
2
Überprüfen Sie dies heraus: igorpolevoy.blogspot.com/2011/01/java-rest-with-ease.html danke igor
ipolevoy
Schauen Sie sich [Resting] ( code.google.com/p/resting ) an. Es verspricht, REST-Services aufzurufen und in einem Schritt eine Liste von Objekten aus der XML / JSON / YAML-Antwort zu erstellen.
Neel
Das Ausruhen hat Probleme mit POST-Anforderungen.
RyanBrady
2
Sie können es auf sehr einfache Weise mit resteasy (von Jboss) tun. Ich habe einen Blog-Beitrag darüber geschrieben, wie man einen Java-REST-Client entwickelt, wenn Sie eine Anleitung für die ersten Schritte benötigen. Auf jeden Fall gibt es in Java Hunderte von Alternativen.
Guido

Antworten:

204

Dies ist eine alte Frage (2008), daher gibt es heute viel mehr Optionen als damals:

UPDATES (Projekte, die 2020 noch aktiv sind):

  • Apache HTTP-Komponenten (4.2) Fließender Adapter - Grundlegender Ersatz für JDK, der von mehreren anderen Kandidaten in dieser Liste verwendet wird. Besser als der alte Commons HTTP Client 3 und einfacher zum Erstellen eines eigenen REST-Clients zu verwenden. Sie müssen so etwas wie Jackson für die JSON-Parsing- Unterstützung verwenden, und Sie können den HTTP-Komponenten-URIBuilder verwenden, um Ressourcen-URIs zu erstellen, die dem Jersey / JAX-RS Rest-Client ähnlich sind. HTTP-Komponenten unterstützen auch NIO, aber ich bezweifle, dass Sie aufgrund der kurzen Anforderung von REST eine bessere Leistung als BIO erzielen. Apache HttpComponents 5 unterstützt HTTP / 2.
  • OkHttp - Grundlegender Ersatz für JDK, ähnlich wie http-Komponenten, der von mehreren anderen Kandidaten in dieser Liste verwendet wird. Unterstützt neuere HTTP-Protokolle (SPDY und HTTP2). Funktioniert unter Android. Leider bietet es keine echte asynchrone Option auf Reaktorschleifenbasis (siehe Ning- und HTTP-Komponenten oben). Wenn Sie jedoch das neuere HTTP2-Protokoll verwenden, ist dies weniger problematisch (vorausgesetzt, die Anzahl der Verbindungen ist problematisch).
  • Ning Async-http-client - bietet NIO-Unterstützung. Früher von Sonatype als Async-http-Client bekannt .
  • Täuschen Sie den Wrapper für http-Clients niedrigerer Ebene vor (okhttp, apache httpcomponents). Erstellt automatisch Clients basierend auf Schnittstellenstubs, die einigen Jersey- und CXF-Erweiterungen ähneln. Starke Federintegration.
  • Retrofit - Wrapper für http-Clients niedrigerer Ebene (okhttp). Erstellt automatisch Clients basierend auf Schnittstellenstubs, die einigen Jersey- und CXF-Erweiterungen ähneln.
  • Volley Wrapper für JDK http Client, von Google
  • google-http wrapper für jdk http client oder apache httpcomponents von google
  • Unirest Wrapper für JDK http Client, von Kong
  • Resteasy JakartaEE-Wrapper für jdk http client von jboss, Teil des jboss-Frameworks
  • jcabi-http- Wrapper für Apache -http- Komponenten, Teil der jcabi-Sammlung
  • Restlet- Wrapper für Apache-http-Komponenten, Teil des Restlet-Frameworks
  • Rest-Assured- Wrapper mit Asserts für einfache Tests

Eine Einschränkung bei der Auswahl von HTTP / REST-Clients. Stellen Sie sicher, dass Sie überprüfen, was Ihr Framework-Stack für einen HTTP-Client verwendet, wie er Threading ausführt, und im Idealfall denselben Client verwenden, wenn er einen anbietet. Wenn Sie also etwas wie Vert.x oder Play verwenden, möchten Sie möglicherweise versuchen, den Backing-Client zu verwenden, um an der vom Framework bereitgestellten Bus- oder Reaktorschleife teilzunehmen. Andernfalls sollten Sie auf möglicherweise interessante Threading-Probleme vorbereitet sein.

Adam Gent
quelle
1
Leider unterstützt der Jersey-Client die PATCH-Methode nicht, wenn sie mit JDK <8
botchniaque
3
Unirest ist sehr einfach zu bedienen, aber aufgrund seines statischen Designs ist es in Shared- und Server-Umgebungen unbrauchbar.
bekce
9
In Bezug auf den unirest Kommentar möchte ich hinzufügen, dass es derzeit (Ende 2016) so aussieht, als ob dieses Projekt nicht mehr gepflegt wird. Es ist sogar ein Problem offen, bei dem nach einem neuen Betreuer gefragt wird.
wegenmic
4
Für diejenigen, die Unirest mögen , habe ich eine Gabelung davon, die derzeit aktiv gewartet / aktualisiert wird.
Josh
3
Es wäre schön, die Antwort in ein Community-Wiki zu
verwandeln
71

Wie ich in diesem Thread erwähnt habe, verwende ich eher Jersey, das JAX-RS implementiert und mit einem netten REST-Client geliefert wird. Das Schöne ist, wenn Sie Ihre RESTful-Ressourcen mit JAX-RS implementieren, kann der Jersey-Client die Entitätsanbieter wie JAXB / XML / JSON / Atom usw. wiederverwenden, sodass Sie auf der Serverseite dieselben Objekte wie Sie wiederverwenden können Verwendung auf dem clientseitigen Unit-Test.

Zum Beispiel ist hier ein Einheit Testfall aus dem Projekt Apache Camel , die XML - Nutzlasten von einer RESTful Ressource sucht (das JAXB Objekt Endpoints verwenden). Die Ressourcenmethode (uri) ist in dieser Basisklasse definiert, die nur die Jersey-Client-API verwendet.

z.B

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

Übrigens hoffe ich, dass die zukünftige Version von JAX-RS eine nette clientseitige API nach dem Vorbild von Jersey hinzufügt

James Strachan
quelle
Gibt es eine Methode, mit der wir die Liste der REST-Service-Server in ClientResource erwähnen können, falls der Server ausfällt, versuchen Sie es mit dem nächsten Server?
Njax3SmmM2x2a0Zf7Hpd
1
Nur ein Update, aber um James '' BTW'-Kommentar zu adressieren, wird die neue Version von JAX-RS 2.0 eine clientseitige API haben: infoq.com/presentations/Java-REST
Nick Klauer
64

Sie können die Standard-Java SE-APIs verwenden:

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

Sie können auch die REST-Client-APIs verwenden, die von JAX-RS-Implementierungen wie Jersey bereitgestellt werden. Diese APIs sind einfacher zu verwenden, erfordern jedoch zusätzliche Jars in Ihrem Klassenpfad.

WebResource resource = client.resource("http://www.example.com/customers"); 
ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "<customer>...</customer."); 
System.out.println(response); 

Weitere Informationen finden Sie unter:

bdoughan
quelle
15
13 Zeilen für einen einfachen Rastanruf im Jahr 2018 klingen viel zu viel ...
Clint Eastwood
1
Sobald Sie Fehlerbehandlung und Optionen hinzugefügt haben, unterscheidet sich dies nicht wesentlich. Wenn der SE-Ansatz lang erscheint, können Sie ihn jederzeit in eine Klasse einschließen ...:> Nach zwei Tagen Debuggen von JAX-RS-Bibliothekskonflikten sind 5 zusätzliche Codezeilen in Ordnung, um den gesamten SPI-Albtraum zu vermeiden.
TekHedd
2
@ClintEastwood Dieser Beitrag wurde geschrieben in 2010
0ddlyoko
12

Wenn Sie nur einen REST-Service aufrufen und die Antwort analysieren möchten, können Sie Rest Assured ausprobieren

// 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]");
Johan
quelle
9

Sie können auch Restlet überprüfen, das über alle clientseitigen Funktionen verfügt und stärker auf REST ausgerichtet ist als Bibliotheken auf niedrigerer Ebene wie HttpURLConnection oder Apache HTTP Client (die wir als Konnektoren nutzen können).

Viele Grüße, Jerome Louvel

Jerome Louvel
quelle
2
Ab dem 24.10.2019 gibt der bereitgestellte Link Folgendes zurück: "Die Restlet-Plattform hat das Ende ihrer Lebensdauer erreicht."
Hans Deragon
6

Sie könnten Rapa versuchen . Teilen Sie uns Ihr Feedback dazu mit. Sie können auch Probleme oder erwartete Funktionen protokollieren.

Jaspis
quelle
1
Rapa hat eine wirklich schöne Oberfläche und wenige Abhängigkeiten. Eine gute Alternative zu RestSharp in der .NET-Welt.
Nachmittag
Projekt sieht tot aus
tkruse
6

Ich möchte auf zwei weitere Optionen hinweisen:

  • Restfulie basiert auf dem VRaptor-Webframework und bietet sowohl server- als auch clientseitige Implementierungen mit sehr guter Hypermedia-Unterstützung.
  • RESTEasy verfügt über eine JAX-RS-Proxy-basierte Client- Implementierung.
Ophir Radnitz
quelle
1
Restfulie sieht tot aus
tkruse
5

Versuchen Sie es JdkRequestvon jcabi-http (ich bin ein Entwickler). So funktioniert es:

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

Weitere Informationen finden Sie in diesem Blogbeitrag: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

yegor256
quelle
5

Ich habe kürzlich Retrofit Library von square ausprobiert. Es ist großartig und Sie können Ihre Rest-API sehr einfach aufrufen. Die auf Anmerkungen basierende Konfiguration ermöglicht es uns, viele Kesselplattencodierungen loszuwerden.

Yasitha Waduge
quelle
4

Ich benutze Apache HTTPClient, um die gesamte HTTP-Seite der Dinge zu handhaben.

Ich schreibe XML-SAX-Parser für den XML-Inhalt, der das XML in Ihr Objektmodell analysiert. Ich glaube, dass Axis2 auch XML -> Modellmethoden verfügbar macht (Achse 1 hat diesen Teil ärgerlich versteckt). XML-Generatoren sind trivial einfach.

Das Codieren dauert nicht lange und ist meiner Meinung nach recht effizient.

JeeBee
quelle
4
Meiner Meinung nach ist dies der schlechteste Weg, um REST zu machen. Die manuelle Handhabung der Serialisierung in Java ist Zeitverschwendung, wenn Sie so viele Optionen wie JAXB und Jackson haben. Selbst das Laden des gesamten Dokuments und die Verwendung von XPath ist geringfügig langsamer als SAX und nichts im Vergleich zum Abrufen von XML (Netzwerkgeschwindigkeit).
Adam Gent
1
Ich stimme auch zu und habe den ursprünglichen Kommentar geschrieben. Damals hatte ich den Wunsch, die Deserialisierung zu kontrollieren, aber heute würde ich Jackson und anständig kommentierte Modellklassen verwenden.
JeeBee
4

OkHttp ist leicht und leistungsstark, wenn es auch mit Retrofit kombiniert wird. Dies funktioniert sowohl für die allgemeine Java-Verwendung als auch für 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();
}

Nachrüstung : http://square.github.io/retrofit/

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

Obwohl es einfach ist, einen HTTP-Client zu erstellen und eine Anfrage zu stellen. Wenn Sie jedoch einige automatisch generierte Clients verwenden möchten, können Sie WADL verwenden, um Code zu beschreiben und zu generieren.

Sie können RestDescribe verwenden , um WSDL zu generieren und zu kompilieren. Sie können damit Clients in PHP, Ruby, Python, Java und C # generieren. Es generiert sauberen Code und es gibt eine gute Änderung, die Sie nach der Codegenerierung etwas anpassen müssen. Eine gute Dokumentation und die zugrunde liegenden Gedanken hinter dem Tool finden Sie hier .

Es gibt nur wenige interessante und nützliche WADL-Tools, die auf Wintermute erwähnt werden.

GG.
quelle
1

Ich habe eine Bibliothek geschrieben, die eine Java-Schnittstelle einem Remote-JSON-REST-Service zuordnet:

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);
}
George Georgovassilis
quelle
0

Schauen Sie sich den http-rest-client an

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

Hier ist ein einfaches Beispiel:

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

Die Bibliothek kümmert sich für Sie um die Serialisierung und Bindung von JSON.

Hier ist ein weiteres Beispiel:

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

Und ein letztes Beispiel:

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

Prost!

g00dnatur3
quelle
0

Beispiele für Jersey Rest Client:
Hinzufügen von Abhängigkeit:

         <!-- 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 und Übergabe von zwei Parametern:

          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 übergibt einen Parameter und erhält eine Antwort von List:

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

Oben gibt es eine Liste zurück, die wir als Liste akzeptieren und dann in Json Array und dann in Json Array in Liste konvertieren.

Wenn Post Request Json Object als Parameter übergibt:

   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 "));
    }
Abhishek Ringsia
quelle
0

Ich verwende derzeit https://github.com/kevinsawicki/http-request. Ich mag ihre Einfachheit und die Art und Weise, wie Beispiele gezeigt werden, aber meistens wurde ich verkauft, als ich las:

Was sind die Abhängigkeiten?

Keiner. Das Ziel dieser Bibliothek ist es, eine einzelne Klassenklasse mit einigen inneren statischen Klassen zu sein. Für das Testprojekt ist Jetty erforderlich, um Anforderungen anhand einer tatsächlichen HTTP-Server-Implementierung zu testen.

Dies löste einige Probleme bei einem Java 1.6-Projekt. Was das Dekodieren von Json in Objekte betrifft, ist Gson einfach unbesiegbar :)

Edoardo
quelle
1
Projekt sieht tot aus, keine
Verpflichtungen