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。