49.4. 解析请求和响应

概述

进行 HTTP 调用的一个基本方面是客户端必须能够解析传出请求消息和传入的响应。在 JAX-RS 2.0 中,关键概念是 实体 类,它代表一个带有介质类型标记的原始消息。为了解析原始消息,您可以注册多个 实体提供程序,其具有将介质类型转换为特定 Java 类型的能力。

换句话说,在 JAX-RS 2.0 上下文中,实体 是原始消息的表示,实体提供程序是提供解析原始消息(基于介质类型)的功能。

实体

实体 是元数据增强的消息正文(媒体类型、语言和编码)。实体 实例以原始格式保存消息,并与特定介质类型关联。要将 实体 对象的内容转换为需要 实体提供商的 Java 对象,它可以将给定介质类型映射到所需的 Java 类型。

变体

javax.ws.rs.core.Variant 对象封装与 实体 关联的元数据,如下所示:

  • 媒体类型,
  • 语言,
  • 编码。

实际上,您可以将 实体 视为由 HTTP 消息内容组成,并由 变体 元数据增强。

实体提供程序

实体提供程序是提供介质类型和 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/xmlapplication/xml 和 media type of the application/*+xml)。
javax.xml.bind.JAXBElement 和 application-supplied JAXB 类
XML 类型(text/xmlapplication/xml 和 media type of the application/*+xml)。
MultivaluedMap<String,String>
表格内容(应用程序/x-www-form-url 编码的)。
StreamingOutput
所有介质类型(*/*)、仅 MessageBodyWriter.
java.lang.Boolean,java.lang.Character,java.lang.Number
仅针对 文本/说明。对应的原语类型通过框/取消框进行转换支持。

响应对象

默认的返回类型是 javax.ws.rs.core.Response 类型,它代表了一个未输入的响应。Response 对象提供对完整 HTTP 响应的访问,包括邮件正文、HTTP 状态、HTTP 标头、媒体类型等。

访问响应状态

您可通过 getStatus 方法访问响应状态(这将返回 HTTP 状态代码):

int status = resp.getStatus();

或者,通过 getStatusInfo 方法,它还提供了描述字符串:

String statusReason = resp.getStatusInfo().getReasonPhrase();

访问返回的标头

您可以使用以下任一方法访问 HTTP 标头:

MultivaluedMap<String,Object>
getHeaders()

MultivaluedMap<String,String>
getStringHeaders()

String
getHeaderString(String name)

例如,如果您知道 ResponseDate 标头,您可以按照如下所示访问它:

String dateAsString = resp.getHeaderString("Date");

访问返回的 cookies

您可以使用 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 通用类型来访问返回的消息,如 ListCollection 类型,您可以使用 javax.ws.rs.core.GenericType<T > construct 指定请求消息类型。例如:

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);