2.2. JAX-RS Client

2.2.1. JAX-RS Client API

JAX-RS 2.0 引入了一个新的客户端 API,用于发送 HTTP 请求到远程 RESTful Web 服务。这是一个流畅的请求构建 API,包含 3 个主要类:

  • 客户端
  • Web 目标
  • 响应

客户端 接口是 Web 目标实例的构建器。WebTarget 代表用于构建子资源 Web 目标或调用请求的不同 URL 或 URL 模板。

可以通过两种方式创建客户端:标准方式,或使用 ResteasyClientBuilder 类。使用 ResteasyClientBuilder 类的优点是它提供了一些额外的帮助程序方法来配置您的客户端。

ResteasyClientBuilder 类提供这些帮助程序方法,但该类特定于 JBoss EAP API。如果要将应用程序迁移到新服务器,您必须重新构建应用程序。ResteasyClientBuilder 类依赖于 RESTEasy,并且类不可移植。

创建客户端的标准方式同时遵循 JAX-RS 和 Java EE API 规范,它在 JAX-RS 实施中可移植。

注意

为确保 JAX-RS 应用保持可移植性,请遵循 Java EE API 规范,如有可能,则使用 Java EE API 应用。如果用例不支持使用 Java EE API,则仅使用特定于 JBoss 的 API。

遵循这些准则可以帮助减少将应用迁移到其他服务器或新的 Java EE 兼容 JBoss 实施时可能出现的问题数量。

使用标准方法创建客户端

以下示例显示了创建客户端的标准方法之一:

Client client = ClientBuilder.newClient();

另外,您可以使用另一种标准方法来创建客户端,如下例所示:

Client client = ClientBuilder.newBuilder().build();
WebTarget target = client.target("http://foo.com/resource");
Response response = target.request().get();
String value = response.readEntity(String.class);
response.close();  // You should close connections!
使用 ResteasyClientBuilder 类创建客户端

以下示例演示了使用 ResteasyClientBuilder 类来创建客户端:

ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target("http://foo.com/resource");

使用 JAX-RS 2.1 时,您可以向 ClientBuilder 类添加两个超时方法。超时方法是符合规格的方法,您可以使用它们,而不使用 RESTEasy 方法。

以下 ClientBuilder 规格兼容方法替换了一些已弃用的 RESTEasy 方法:

  • connectTimeout 方法替换了 create ConnectionTimeout 方法。

    connectTimeout 方法决定了客户端在进行新服务器连接时必须等待的时长。

  • readTimeout 方法替换了 socketTimeout 方法。

    readTimeout 方法决定了客户端必须等待来自服务器的响应的时长。

以下示例显示了 connectTimeout 和 readTimeout 方法 的指定值:

import javx.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Client;

Client client = ClientBuilder.newBuilder()
	       .connectTimeout(100, TimeUnit.SECONDS)
	       .readTimeout(2, TimeUnit.SECONDS)
	       .build();

请注意 ,readTimeout 适用于现有连接上已执行的请求。

注意

将 timeout 参数的值设置为零会导致服务器无限期等待。

RESTEasy 自动加载一组默认提供程序,其中包含 META-INF/services/javax.ws.rs.ext.Providers 文件中列出的所有类。另外,您可以通过方法调用 Client.configuration() 提供的配置对象手动注册其他提供程序、过滤器和拦截器。通过配置,您可以设置可能需要的配置属性。

每个 Web 目标 都有一个配置实例,它继承了与父实例注册的组件和属性。这可让您为每个目标资源设置特定的配置选项,例如用户名和密码。

其它资源

使用 RESTEasy 客户端类

您必须将 RESTEasy 客户端的以下依赖项添加到 Maven pom.xml 文件中:

<dependency>
	<groupId>org.jboss.resteasy</groupId>
	<artifactId>resteasy-client</artifactId>
	<version>VERSION_IN_EAP</version>
 </dependency>

有关使用 RESTEasy 客户端类 的工作示例,请参见 JBoss EAP 附带的 jaxrs-client 和 resteasy-jaxrs-client 快速入门。

客户端过滤器

客户端具有两种过滤器:

ClientRequestFilter
ClientRequestFilter 在通过线路将 HTTP 请求发送到服务器之前运行。ClientRequestFilter 也被允许中止请求执行并提供修剪的响应,而无需通过线路传输到服务器。
ClientResponseFilter
ClientResponseFilter 在从服务器收到响应后运行,但在取消托管响应正文之前。ClientResponseFilter 可以在将响应对象提交到应用代码之前对其进行修改。以下示例演示了这些概念:
// execute request filters
for (ClientRequestFilter filter : requestFilters) {
	filter.filter(requestContext);
	if (isAborted(requestContext)) {
    return requestContext.getAbortedResponseObject();
  }
}

// send request over the wire
response = sendRequest(request);

// execute response filters
for (ClientResponseFilter filter : responseFilters) {
	filter.filter(requestContext, responseContext);
}
将客户端过滤器注册到客户端请求

以下示例演示了如何将客户端过滤器注册到客户端请求:

client = ClientBuilder.newClient();
WebTarget base = client.target(generateURL("/") + "get");
base.register(ClientExceptionsCustomClientResponseFilter.class).request("text/plain").get();
客户端缓存

RESTEasy 能够设置客户端缓存。此缓存查找随服务器响应发回的 cache-control 标头。如果 cache-control 标头指定允许客户端缓存响应,RESTEasy 会将它缓存在本地内存中。

ResteasyWebTarget target = client.target(generateBaseUrl());
target.register(BrowserCacheFeature.class);
块编码支持

RESTEasy 为客户端 API 提供指定请求应在区块传输模式中发送的功能可以通过两种方式指定区块传输模式,如下所示:

  • 您可以将 org.jboss.resteasy.client.jaxrs.ResteasyWebTarget 配置为以区块模式发送所有请求:

    ResteasyClient client = new ResteasyClientBuilder().build();
    ResteasyWebTarget target = client.target("http://localhost:8081/test");
    target.setChunked(b.booleanValue());
    Invocation.Builder request = target.request();
  • 另外,您还可以将特定请求配置为以块模式发送:

    ResteasyClient client = new ResteasyClientBuilder().build();
    ResteasyWebTarget target = client.target("http://localhost:8081/test");
    ClientInvocationBuilder request = (ClientInvocationBuilder) target.request();
    request.setChunked(b);

    javax.ws.rs.client.Invocation.Builder 类不同,org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder 是 RESTEasy 类。

注意

以块模式发送请求的能力取决于底层传输层。特别是,它取决于所使用的 org.jboss.resteasy.client.jaxrs.ClientHttpEngine 类的实施。目前,只有 ApacheHttpClient43Engine 和之前实施 ApacheHttpClient4Engine 的默认实施支持区块模式。这两个都位于 org.jboss.resteasy.client.jaxrs.engines 软件包中如需更多信息,请参阅通过 HTTP 客户端实施 RESTEasy 部分。