49.4. 解析请求和响应
概述
进行 HTTP 调用的一个重要方面是客户端必须能够解析传出请求消息和传入响应。在 JAX-RS 2.0 中,密钥概念是 Entity
类,它代表带有介质类型标记的原始消息。要解析原始消息,您可以注册多个 实体供应商,该用户能够将介质类型转换为或从特定的 Java 类型转换。
换句话说,在 JAX-RS 2.0 上下文中,实体表示原始消息,实体提供程序是提供解析原始消息的功能(基于介质类型)。
实体
Entity
是由元数据(媒体类型、语言和编码)增强的消息正文。Entity
实例以原始格式保存消息,并与特定介质类型相关联。要将 实体
对象的内容转换为 Java 对象,您需要 实体提供程序,该提供程序 能够将给定介质类型映射到所需的 Java 类型。
变体
javax.ws.rs.core.Variant
对象封装与 实体关联的元数据
,如下所示:
- 媒体类型,
- 语言,
- 编码。
实际上,您可以将 实体
视为由 HTTP 消息内容组成,由 Variant
元数据增强。
实体供应商
实体提供程序是一个类,提供介质类型和 Java 类型之间的映射功能。实际上,您可以将实体供应商视为一个类,它提供解析特定介质类型的消息(或者可能有多个介质类型)。实体供应商有两个不同的变体:
MessageBodyReader
- 提供从介质类型映射到 Java 类型的能力。
MessageBodyWriter
- 提供从 Java 类型映射到介质类型的能力。
标准实体供应商
以下 Java 和介质类型组合的实体供应商作为标准提供:
byte[]
-
所有介质类型(
(
条件为 )。 java.lang.String
-
所有介质类型(
(
条件为 )。 java.io.InputStream
-
所有介质类型(
(
条件为 )。 java.io.Reader
-
所有介质类型(
(
条件为 )。 java.io.File
-
所有介质类型(
(
条件为 )。 javax.activation.DataSource
-
所有介质类型(
(
条件为 )。 javax.xml.transform.Source
-
XML 类型(
text/xml
,application/xml
,, 和 media type of theapplication ldapsearch+xml
)。 javax.xml.bind.JAXBElement
和 application-supplied JAXB 类-
XML 类型(
text/xml
,application/xml
,, 和 media type of theapplication ldapsearch+xml
)。 MultivaluedMap<String,String>
-
表单内容(
application/x-www-form-urlencoded
)。 StreamingOutput
-
所有介质类型(
*authorize
),MessageBodyWriter
only. java.lang.Boolean
,java.lang.Character
,java.lang.Number
-
仅适用于
text/plain
。通过 boxing/unboxing 转换支持相应的原语类型。
响应对象
默认返回类型是 javax.ws.rs.core.Response
类型,它代表未输入的响应。Response
对象提供对完整的 HTTP 响应的访问,包括消息正文、HTTP 状态、HTTP 标头、媒体类型等。
访问响应状态
您可以通过 getStatus
方法(返回 HTTP 状态代码)访问响应状态:
int status = resp.getStatus();
或者 getStatusInfo
方法,它还提供 description 字符串:
String statusReason = resp.getStatusInfo().getReasonPhrase();
访问返回的标头
您可以使用以下任一方法访问 HTTP 标头:
MultivaluedMap<String,Object> getHeaders() MultivaluedMap<String,String> getStringHeaders() String getHeaderString(String name)
例如,如果您知道 Response
具有 Date
标头,您可以按照以下方式访问它:
String dateAsString = resp.getHeaderString("Date");
访问返回的 Cookie
您可以使用 getCookies
方法访问 Response
中设置的任何新 Cookie,如下所示:
import javax.ws.rs.core.NewCookie; ... java.util.Map<String,NewCookie> cookieMap = resp.getCookies(); java.util.Collection<NewCookie> cookieCollection = cookieMap.values();
访问返回的消息内容
您可以通过调用 Response
对象的 readEntity
方法之一来访问返回的消息内容。readEntity
方法自动调用可用的实体提供程序,将消息转换为请求的类型(指定为 readEntity
的第一个参数)。例如,将消息内容作为 String
类型访问:
String messageBody = resp.readEntity(String.class);
集合返回值
如果您需要将返回的消息作为 Java 通用类型(例如,列表
或 集合
类型)访问返回的消息,您可以使用 javax.ws.rs.core.GenericType<T
> 构造来指定请求消息类型。例如:
import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Client; import javax.ws.rs.core.GenericType; import java.util.List; ... GenericType<List<String>> stringListType = new GenericType<List<String>>() {}; Client client = ClientBuilder.newClient(); List<String> bookNames = client.target("http://example.org/bookstore/booknames") .request("text/plain") .get(stringListType);