在 RESTful 应用程序中定义资源的介质类型
资源以多种格式表示。您可以使用 XML、JavaScript 对象表示法 (JSON)、Atom、二进制格式(例如 PNG、JPEG 和 GIF)、纯文本以及专用格式来表示资源。具象状态传输 (REST) 使您能够以多种格式灵活地表示单一资源。
开始之前
在 JAX-RS Web 应用程序中定义资源。
关于此任务
资源具有表示。资源表示是通过 URI 发送到资源或者从资源返回的 HTTP 消息中的内容。资源所支持的每种表示都有相应的介质类型。例如,如果资源将要返回格式化为 XML 的内容,那么您可以使用 application/xml 作为 HTTP 消息中的相关联介质类型。
根据应用程序的需求不同,资源可以返回首选单一格式的表示,也可以返回多种格式的表示。例如,使用 JavaScript 客户机访问的资源可能会由于 JSON 易于使用而选择 JSON 表示。
JAX-RS 提供了 @Consumes 和 @Produces 注释,用于声明资源方法能够读写的介质类型。
JAX-RS 还使用实体提供程序在 Java™ 类型与资源表示之间进行相互映射。MessageBodyReader 实体提供程序读取请求实体,然后将请求实体反序列化为 Java 类型。MessageBodyWriter 实体提供程序将 Java 类型序列化为响应实体。
Java 类型 | MessageBodyReader | MessageBodyWriter | 受支持的内容类型 |
---|---|---|---|
byte[] | X | X | */* |
java.io.InputStream | X | X | */* |
java.io.Reader | X | X | */* |
java.lang.String | X | X | */* |
java.io.File | X | X | */* |
javax.activation.DataSource | X | X | */* |
javax.xml.transform.Source | X | X | text/xml、application/xml 和 application/*+xml |
javax.ws.rs.core.MultivaluedMap | X | X | application/x-www-form-urlencoded |
JAXB 类型 | X | X | text/xml、application/xml 和 application/*+xml |
javax.ws.rs.core.StreamingOutput | X | */* |
如果将 String 值用作请求实体参数,那么 MessageBodyReader 实体提供程序会将请求体反序列化为 String。如果将 JAXB 类型用作资源方法的返回类型,那么 MessageBodyWriter 会将 Java XML 绑定体系结构 (JAXB) 对象序列化为响应体。
如果您需要从 Java 类型到特定表示的定制映射,请参阅有关使用应用程序定义的实体提供程序的信息。
如果客户机可以处理多种格式,并且您希望服务器确定要返回的最佳资源表示,请参阅有关在 JAX-RS 应用程序中通过内容协商来处理多种内容类型的信息。
XML、JSON 和 Atom 的规范提供了关于应用程序的资源表示格式的详细信息。请参阅这些规范以进一步了解资源表示格式。
过程
- 确定用于请求或响应的资源表示格式,例如 XML、JSON 或 ATOM。
- 适当地将 @Consumes 和 @Produces 资源添加到资源方法。
- 如果资源需要读取请求内容,请对资源方法添加请求实体参数。 请求实体参数是没有注释的方法的单一 Java 参数。
- 如果资源方法在响应中返回了内容,请返回 JAX-RS 实体提供程序可写的 Java 对象。 此 Java 对象将映射到 HTTP 响应中的响应实体。返回的对象必须是 JAX-RS 支持的 Java 类型或者包装在 javax.ws.rs.core.Response 或 javax.ws.rs.core.GenericEntity 类型中。
结果
您已将请求实体映射到资源方法实体参数,并且,返回的任何响应对象都将映射到资源表示的响应实体。
示例
以下示例说明将 XML 定义为 RESTful 书店应用程序的资源表示。
- 标识要读取请求实体或返回响应实体的资源方法。
在随后的 retrieveSpecificBookInformation 方法示例中,没有要读取的请求实体。但是,存在要返回的响应对象。此对象包装 JAXB 对象,后者包含实体信息。对资源方法添加介质类型为 application/xml 的 @Produces 注释表明,该资源方法始终返回介质类型为 application/xml 的 XML 表示。
具有与 application/xml 介质类型兼容的 Accept HTTP 请求头值的客户机将正确地调用该方法。
不具有与 application/xml 介质类型兼容的 Accept HTTP 头值的客户机将自动接收到 406 Not Acceptable 响应状态,这表示服务器无法生成可接受的响应。
以下示例标识用于读取请求实体或返回响应实体的资源方法:
/* * Book.java * This class represents individual books. The @Produces annotation specifies a media type of application/xml. */ @Path(“/bookstore/books/{bookID}”) public class Book { @GET @Produces(“application/xml”) public javax.ws.rs.core.Response retrieveSpecificBookInformation(@PathParam(“bookID”) String theBookID, @Context javax.ws.rs.core.HttpHeaders headers) { /* … */ return Response.ok(/* JAXB object to represent response body entity */).expires(/* Expires response header value*/).header(“CustomHeaderName”, “CustomHeaderValue”).build(); } @PUT public String updateBookInformation(@PathParam(“bookID”) String theBookID, String theRequestEntity, @javax.ws.rs.HeaderParam(“Content-Length”) String contentLengthHeader) { /* … */ } @DELETE public void removeBook(@PathParam(“bookID”) String theBookID) { /* … */ } }
- 标识需要使用请求信息的资源方法。
在以下片段中,如果已发送介质类型 text/plain,那么书籍资源的 PUT 方法将接受请求实体内容(由 @Consumes 注释定义)。此方法将返回具有 text/plain 表示的内容(由 @Produces 注释指定)。
如果客户机未发送 Content-Type 值为 text/plain 的消息,那么将不会调用 PUT 资源方法。如果在 HTTP 请求头中发送了 Content-Type: application/xml,那么将不会调用 Java 方法 updateBookInformation。
DELETE 方法既不读取请求实体也不返回响应实体;因此,它不需要 @Consumes 或 @Produces 注释。
以下示例标识了使用请求信息的资源方法:
/* * Book.java * This class represents represent individual books with custom headers. */ @Path(“/bookstore/books/{bookID}”) public class Book { @GET @Produces(“application/xml”) public javax.ws.rs.core.Response retrieveSpecificBookInformation(@PathParam(“bookID”) String theBookID, @Context javax.ws.rs.core.HttpHeaders headers) { /* … */ return Response.ok(/* JAXB object to represent response body entity */).expires(/* Expires response header value).header(“CustomHeaderName”, “CustomHeaderValue”).build(); } @PUT @Consumes(“text/plain”) @Produces(“text/plain”) public String updateBookInformation(@PathParam(“bookID”) String theBookID, String theRequestEntity, @javax.ws.rs.HeaderParam(“Content-Length”) String contentLengthHeader) { /* … */ String responseEntity = /* a plain text representation */; return responseEntity; } @DELETE public void removeBook(@PathParam(“bookID”) String theBookID) { /* … */ } }
下一步做什么
请参阅 JAX-RS 规范,以获取所有支持表示的标准介质格式的列表。
高级用户可以考虑定义从 Java 类型到表示的定制映射或者使用客户机内容协商功能来确定首选资源表示。要了解更多有关这些选项的信息,请参阅“使用定制实体格式”信息或“通过内容协商来处理多种内容类型”信息。