Chapter 20. Multipart Providers
RESTEasy has rich support for the
multipart/*
and multipart/form-data
MIME (Multipurpose Internet Mail Extension) types. The multipart
MIME format passes lists of content bodies. Multiple content bodies are embedded in the one message. multipart/form-data
is often found in web application HTML Form documents, and is generally used to upload files. The form-data
format works like other multipart
formats, except that each inlined piece of content has a name associated with it.
RESTEasy provides a custom API for reading and writing
multipart
types, as well as marshaling arbitrary List (for any multipart
type) and Map (multipart/form-data
only) objects.
20.1. Input with multipart/mixed
When you write a JAX-RS service, RESTEasy provides an interface to let you read any
multipart
MIME type: org.jboss.resteasy.plugins.providers.multipart.MultipartInput
.
package org.jboss.resteasy.plugins.providers.multipart; public interface MultipartInput { List<InputPart> getParts(); String getPreamble(); } 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(); }
MultipartInput
is a simple interface that lets you access each part of the multipart
message. Each part is represented by an InputPart
interface, and is associated with a set of headers. You can unmarshal a part by calling one of the getBody()
methods. The Type genericType
parameter can be null, but the Class type
parameter must be set. RESTEasy locates a MessageBodyReader
based on the media type of the part, and the type information you pass in. The following piece of code unmarshals XML parts into a JAXB annotated class called Customer
.
@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); } } }
If you want to unmarshal a body part that is sensitive to generic type metadata, you can use the
org.jboss.resteasy.util.GenericType
class, like so:
@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<<() {}); } } }
GenericType
is required here because it is the only way to obtain generic type information at runtime.