49.3. 构建客户端调用

概述

在构建目标 URI 后,使用 WebTarget 构建器类后,下一步是配置请求的其他方面,如 HTTP 标头、cookies 等。构建调用的最后一个步骤是调用适当的 HTTP 动词(GET、POST、PUT 或 DELETE),并在需要时提供一个消息正文。

invocation.Builder 类

javax.ws.rs.client.Invocation.Builder 构建器类提供 fluent API 的一部分,可让您构建 HTTP 消息的内容并调用 HTTP 方法。

创建调用构建器

若要创建 Invocation.Builder 实例,可在 javax.ws.rs.client.WebTarget 实例上调用 一个请求 方法。例如:

// Java
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.client.Invocation.Builder;
...
WebTarget books = client.target("http://example.org/bookstore/books/123");
Invocation.Builder invbuilder = books.request();

定义 HTTP 标头

您可以使用标头方法在请求消息中添加 HTTP 标头,如下所示:

Invocation.Builder invheader = invbuilder.header("From", "fionn@example.org");

定义 cookies

您可以使用 cookie 方法在请求消息中添加 Cookie,如下所示:

Invocation.Builder invcookie = invbuilder.cookie("myrestclient", "123xyz");

定义属性

您可以使用 属性方法在这个请求的上下文中设置属性,如下所示:

Invocation.Builder invproperty = invbuilder.property("Name", "Value");

定义可接受的介质类型、语言或编码

您可以定义接受的介质类型、语言或编码,如下所示:

Invocation.Builder invmedia = invbuilder.accept("application/xml")
                                        .acceptLanguage("en-US")
                                        .acceptEncoding("gzip");

调用 HTTP 方法

构建 REST 调用的过程通过调用 HTTP 方法终止,该方法执行 HTTP 调用。可以调用以下方法(继承于 javax.ws.rs.client.SyncInvoker 基础类):

get
post
delete
put
head
trace
options

如果您想要调用的特定 HTTP 动词不在此列表中,您可以使用通用方法 方法调用 任何 HTTP 方法。

输入的响应

所有 HTTP 调用方法均提供无类型变体和输入变体(使用额外参数)。如果使用默认的 get() 方法(不使用参数)调用请求,则 javax.ws.rs.core.Response 对象从调用返回。例如:

Response res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").get();

但是,也可以使用 get(Class<T>) 方法请求将响应返回为特定类型的值。例如,要调用请求并要求将响应返回为 BookInfo 对象:

BookInfo res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").get(BookInfo.class);

但是,为了解决这个问题,您必须将合适的 实体提供程序 注册到 客户端 实例,后者能够将响应格式 application/xml 映射到请求的类型。有关实体供应商的详情,请参考 第 49.4 节 “解析请求和响应”

在 post 或 put 中指定传出消息

对于在请求中包含消息正文的 HTTP 方法(如 POST 或 PUT),您必须将消息正文指定为方法的第一个参数。邮件正文必须指定为 javax.ws.rs.client.Entity 对象,其中 实体 封装消息内容及其关联的媒体类型。例如,要调用 POST 方法,消息内容以 String 类型形式提供:

import javax.ws.rs.client.Entity;
...
Response res = client.target("http://example.org/bookstore/registerbook")
                     .request("application/xml")
                     .put(Entity.entity("Red Hat Install Guide", "text/plain"));

如有必要,实体.entity() 构造器方法将使用注册的实体提供商自动将提供的消息实例映射到指定的介质类型。总是可以将消息正文指定为一个简单的 String 类型。

延迟调用

除了立即调用 HTTP 请求(例如,调用 get() 方法),您可以选择创建 javax.ws.rs.client.Invocation 对象,稍后可以调用该请求。Invocation 对象 封装 待处理调用的所有详情,包括 HTTP 方法。

可以使用以下方法构建 Invocation 对象:

buildGet
buildPost
buildDelete
buildPut
build

例如,要创建一个 GET Invocation 对象并在以后调用它,您可以使用类似如下的代码:

import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Response;
...
Invocation getBookInfo = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml").buildGet();
...
// Later on, in some other part of the application:
Response = getBookInfo.invoke();

异步调用

JAX-RS 2.0 客户端 API 支持客户端侧的异步调用。要进行异步调用,只需在以下 request() 方法链中调用 async() 方法。例如:

Future<Response> res = client.target("http://example.org/bookstore/books/123")
                     .request("application/xml")
                     .async()
                     .get();

当您进行异步调用时,返回的值为 java.util.concurrent.Future 对象。有关异步调用的详情,请参考 第 49.6 节 “客户端上的异步处理”