RESTEasy Client API

RESTEasy Client API

1. Einführung

Inprevious article haben wir uns auf die serverseitige Implementierung vonJAX-RS 2.0 inRESTEasykonzentriert.

JAX-RS 2.0 führt eine neue Client-API ein, mit der Sie HTTP-Anforderungen an Ihre Remote-RESTful-Webdienste senden können. Jersey, Apache CXF, Restlet und RESTEasy sind nur einige der beliebtesten Implementierungen.

In diesem Artikel erfahren Sie, wie SieREST API verbrauchen, indem Sie Anforderungen mitRESTEasy API senden.

2. Projektaufbau

Fügen Sie in Ihrenpom.xml die folgende Abhängigkeit hinzu:


    3.0.14.Final


    
        org.jboss.resteasy
        resteasy-client
        ${resteasy.version}
    
    ...

3. Client-seitiger Code

Die Client-Implementierung ist recht einfach und besteht aus drei Hauptklassen:

    • Klient

    • WebTarget

    • Antwort

DieClient-Schnittstelle ist ein Builder vonWebTarget-Instanzen.

WebTarget stellt eine eindeutige URL oder URL-Vorlage dar, aus der Sie weitere WebTargets für Unterressourcen erstellen oder Anforderungen aufrufen können.

Es gibt zwei Möglichkeiten, einen Client zu erstellen:

  • Der Standardweg unter Verwendung vonorg.jboss.resteasy.client.ClientRequest

  • RESTeasy Proxy Framework: unter Verwendung der KlasseResteasyClientBuilder

Wir werden uns hier auf das RESTEasy Proxy Framework konzentrieren.

Anstatt JAX-RS-Annotationen zu verwenden, um eine eingehende Anforderung Ihrer RESTFul-Webdienstmethode zuzuordnen, erstellt das Client-Framework eine HTTP-Anforderung, die zum Aufrufen eines Remote-RESTful-Webdiensts verwendet wird.

Beginnen wir also damit, eine Java-Schnittstelle zu schreiben und JAX-RS-Anmerkungen zu den Methoden und zur Schnittstelle zu verwenden.

3.1. DieServicesClient-Schnittstelle

@Path("/movies")
public interface ServicesInterface {

    @GET
    @Path("/getinfo")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    Movie movieByImdbId(@QueryParam("imdbId") String imdbId);

    @POST
    @Path("/addmovie")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    Response addMovie(Movie movie);

    @PUT
    @Path("/updatemovie")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    Response updateMovie(Movie movie);

    @DELETE
    @Path("/deletemovie")
    Response deleteMovie(@QueryParam("imdbId") String imdbId);
}

3.2. Die Filmklasse

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "movie", propOrder = { "imdbId", "title" })
public class Movie {

    protected String imdbId;
    protected String title;

    // getters and setters
}

3.3. Die Anforderungserstellung

Wir generieren jetzt einen Proxy-Client, mit dem wir die API verwenden können:

String transformerImdbId = "tt0418279";
Movie transformerMovie = new Movie("tt0418279", "Transformer 2");
final String path = "http://127.0.0.1:8080/RestEasyTutorial/rest";

ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(path));
ServicesInterface proxy = target.proxy(ServicesInterface.class);

// POST
Response moviesResponse = proxy.addMovie(transformerMovie);
System.out.println("HTTP code: " + moviesResponse.getStatus());
moviesResponse.close();

// GET
Movie movies = proxy.movieByImdbId(transformerImdbId);

// PUT
transformerMovie.setTitle("Transformer 4");
moviesResponse = proxy.updateMovie(transformerMovie);
moviesResponse.close();

// DELETE
moviesResponse = proxy.deleteMovie(batmanMovie.getImdbId());
moviesResponse.close();

Beachten Sie, dass die RESTEasy-Client-API auf ApacheHttpClientbasiert.

Beachten Sie auch, dass wir nach jeder Operation die Antwort schließen müssen, bevor wir eine neue Operation ausführen können. Dies ist erforderlich, da der Client standardmäßig nur über eine einzige HTTP-Verbindung verfügt.

Beachten Sie abschließend, wie wir direkt mit den DTOs arbeiten. Wir beschäftigen uns nicht mit der Marschall- / Unmarschall-Logik von und zuJSON oderXML. Dies geschieht hinter den Kulissen mitJAXB oderJackson, da die KlasseMovie mit. ordnungsgemäß kommentiert wurde

3.4. Die Anforderungserstellung mit Verbindungspool

Eine Anmerkung aus dem vorherigen Beispiel war, dass wir nur eine einzige Verbindung zur Verfügung hatten. Wenn wir zum Beispiel versuchen:

Response batmanResponse = proxy.addMovie(batmanMovie);
Response transformerResponse = proxy.addMovie(transformerMovie);

ohneclose() aufbatmanResponse aufzurufen - eine Ausnahme wird ausgelöst, wenn die zweite Zeile ausgeführt wird:

java.lang.IllegalStateException:
Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.

Wiederum - dies geschieht einfach, weil der von RESTEasy verwendete StandardHttpClientorg.apache.http.impl.conn.SingleClientConnManager ist - was natürlich nur eine einzige Verbindung verfügbar macht.

Um diese Einschränkung zu umgehen, muss die Instanz vonRestEasyClientanders erstellt werden (mit einem Verbindungspool):

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build();
cm.setMaxTotal(200); // Increase max total connection to 200
cm.setDefaultMaxPerRoute(20); // Increase default max connection per route to 20
ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient);

ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
ResteasyWebTarget target = client.target(UriBuilder.fromPath(path));
ServicesInterface proxy = target.proxy(ServicesInterface.class);

Jetzt können wirbenefit from a proper connection pool und mehrere Anforderungen über unseren Client ausführen, ohne dass die Verbindung jedes Mal freigegeben werden muss.

4. Fazit

In diesem kurzen Tutorial haben wir dieRESTEasy Proxy Framework vorgestellt und damit eine supereinfache Client-API erstellt.

Das Framework bietet einige weitere Hilfsmethoden zum Konfigurieren eines Clients und kann als Spiegel der serverseitigen JAX-RS-Spezifikationen definiert werden.

Das in diesem Artikel verwendete Beispiel ist alssample project in GitHub verfügbar.