2.7.11. JAX-RS 中的多部分提供程序
多部分 MIME 格式用于传递嵌入在同一消息中的内容正文列表。多部分 MIME 格式的一个示例是 multipart/form-data
MIME 类型。这通常在 Web 应用 HTML 表单文档中找到,通常用于上传文件。此 MIME 类型的格式 数据
格式与其他多部分格式相同,不同之处在于每个内嵌的内容都有相关联的名称。
RESTEasy 允许 multipart/form-data
和 multipart/*
MIME 类型。RESTEasy 还提供了自定义 API,用于读取和写入多部分类型,以及托管任意 列表
(任何多部分类型)和 Map
(仅限多部件/数据)对象。
有许多框架通过过滤器和拦截器(如 Seam 中的 org.jboss.seam.web.MultipartFilter
)和 Spring 中的 org.springframework.web.multipart.MultipartResolver
自动进行多部分解析。但是,传入的多部分请求流只能被解析一次。使用多部分的 RESTEasy 用户应确保在 RESTEasy 获取流之前不会解析流。
2.7.11.1. 多部分数据输入
编写 JAX-RS 服务时,RESTEasy 提供 org.jboss.resteasy.plugins.providers.multipart.MultipartInput
接口,以便您可以在任何多部分 MIME 类型中进行读取。
package org.jboss.resteasy.plugins.providers.multipart; public interface MultipartInput { List<InputPart> getParts(); String getPreamble(); // You must call close to delete any temporary files created // Otherwise they will be deleted on garbage collection or on JVM exit void close(); } public interface InputPart { MultivaluedMap<String, String> getHeaders(); String getBodyAsString(); <T> T getBody(Class<T> type, Type genericType) throws IOException; <T> T getBody(org.jboss.resteasy.util.GenericType<T> type) throws IOException; MediaType getMediaType(); boolean isContentTypeFromMessage(); }
MultipartInput
是一个简单界面,可让您访问多部分消息的每个部分。每个部分都由一个 InputPart
接口表示,每个部分都有一组与其关联的标头。您可以通过调用其中一个 getBody()
方法来解译该部分。genericType
参数可以是 null
,但必须设置 type
参数。RESTEasy 将根据部分的媒体类型以及您传递的类型信息查找 MessageBodyReader
。
2.7.11.1.1. 多部分/混合
输入
示例: Unmarshalling 部分
@Path("/multipart") public class MyService { @PUT @Consumes("multipart/mixed") public void put(MultipartInput input) { List<Customer> customers = new ArrayList...; for (InputPart part : input.getParts()) { Customer cust = part.getBody(Customer.class, null); customers.add(cust); } input.close(); } }
上例假定 客户
类标注了 JAXB。
有时,您可能想要解译对通用类型的元数据敏感的正文部分。在这种情况下,您可以使用 org.jboss.resteasy.util.GenericType
类。
示例:将 Type Sensitive Unmarshalling a Generic Type Metadata
@Path("/multipart") public class MyService { @PUT @Consumes("multipart/mixed") public void put(MultipartInput input) { for (InputPart part : input.getParts()) { List<Customer> cust = part.getBody(new GenericType<List<Customer>>() {}); } input.close(); } }
需要使用 GenericType
,因为它是在运行时获取通用类型信息的唯一方法。
2.7.11.1.2. 多部分/mixed
和 java.util.List
输入
如果正文部分是统一的,您不必手动解译每个部分。您只需提供 java.util.List
作为您的输入参数。它的类型必须与 List
类型声明的 generic 参数解开。
示例:解压
客户
列表
@Path("/multipart") public class MyService { @PUT @Consumes("multipart/mixed") public void put(List<Customer> customers) { ... } }
上例假定 客户
类标注了 JAXB。
2.7.11.1.3. 使用 multipart/form-data
输入
在编写 JAX-RS 服务时,RESTEasy 提供了一个接口,允许您在 多部件/格式数据
MIME 类型中读取。多部分/格式数据
通常在 Web 应用 HTML 表单文档中找到,通常用于上传文件。form-data
格式与其他多部分格式相同,不同之处在于每个内嵌的内容都有相关联的名称。用于表单数据输入的界面为 org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput
。
示例: MultipartFormDataInput Interface
public interface MultipartFormDataInput extends MultipartInput { @Deprecated Map<String, InputPart> getFormData(); Map<String, List<InputPart>> getFormDataMap(); <T> T getFormDataPart(String key, Class<T> rawType, Type genericType) throws IOException; <T> T getFormDataPart(String key, GenericType<T> type) throws IOException; }
它的工作方式与 前面描述的 MultipartInput
基本相同。
2.7.11.1.4. 带有 multipart/form-data
的 Java.util.Map
使用表单数据时,如果正文部分是统一的,您不必手动分隔每个部分和每个部分。您只需将 java.util.Map
作为输入参数提供。它的类型必须与 List
类型声明的 generic 参数解开。
示例:解压 客户
对象的映射
@Path("/multipart") public class MyService { @PUT @Consumes("multipart/form-data") public void put(Map<String, Customer> customers) { ... } }
上例假定 客户
类标注了 JAXB。