RESTEasy客户端API

RESTEasy Client API

1.简介

在上一篇文章中,我们重点介绍了JAX-RS 2.0的RESTEasy服务器端实现。

JAX-RS 2.0引入了新的客户端API,因此您可以向远程RESTful Web服务发出HTTP请求。泽西岛,Apache CXF,Restlet和RESTEasy只是最受欢迎的实现的一部分。

在本文中,我们将探讨如何通过使用RESTEasy API发送请求来使用REST API。

2.项目设置

在pom.xml中添加以下依赖项:

1
2
3
4
5
6
7
8
9
10
11
<properties>
    <resteasy.version>3.0.14.Final</resteasy.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        resteasy-client</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
    ...
</dependencies>

3.客户端代码

客户端实现相当,由3个主要类组成:

  • 客户

  • WebTarget

  • 响应

  • 客户

  • WebTarget

  • 响应

  • 客户端接口是WebTarget实例的构建器。

    WebTarget代表一个独特的URL或URL模板,您可以从中构建更多的子资源WebTarget或对其调用请求。

    实际上,有两种创建客户端的方法:

  • 使用org.jboss.resteasy.client.ClientRequest的标准方法

  • RESTeasy代理框架:通过使用ResteasyClientBuilder类

  • 在这里,我们将重点介绍RESTEasy代理框架。

    客户端框架没有使用JAX-RS批注将传入的请求映射到RESTFul Web Service方法,而是构建了一个HTTP请求,用于在远程RESTful Web Service上调用。

    因此,让我们开始编写Java接口并在方法和接口上使用JAX-RS批注。

    3.1。 ServicesClient界面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    @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。电影课

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name ="movie", propOrder = {"imdbId","title" })
    public class Movie {

        protected String imdbId;
        protected String title;

        // getters and setters
    }

    3.3。请求创建

    现在,我们将生成可用于使用API??的代理客户端:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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();

    请注意,RESTEasy客户端API基于Apache HttpClient。

    另请注意,在执行每个操作之后,我们需要先关闭响应,然后才能执行新操作。这是必需的,因为默认情况下,客户端只有一个HTTP连接可用。

    最后,请注意我们是如何直接与DTO一起工作的-我们不处理往返于JSON或XML的编组/解组逻辑;因为正确注释了Movie类,所以使用JAXB或Jackson发生在幕后。

    3.4。使用连接池创建请求

    上一个示例的一个注释是,我们只有一个连接可用。例如,如果我们尝试执行以下操作:

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

    在batmanResponse上不调用close()的情况下–执行第二行时将引发异常:

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

    同样,这是发生的,因为RESTEasy使用的默认HttpClient是org.apache.http.impl.conn.SingleClientConnManager-当然,它仅使单个连接可用。

    现在–要解决该限制–必须以不同的方式(使用连接池)创建RestEasyClient实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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);

    现在,我们可以受益于适当的连接池,并且可以通过客户端运行多个请求,而不必每次都释放连接。

    4。结论

    在本快速教程中,我们介绍了RESTEasy代理框架,并使用它构建了一个超级简单的客户端API。

    该框架为我们提供了更多的辅助方法来配置客户端,并且可以定义为与JAX-RS服务器端规范相反的镜像。

    本文中使用的示例可在GitHub中作为示例项目获得。