beerye beerye - 3 months ago 54
reST (reStructuredText) Question

A message body reader for FormDataMultiPart was not found

I'm having some trouble with using FormDataMultiPart.

For some reason it looks as if the config for MultiPartFeature isn't getting called, even though i have put it in my web.xml, here is my code below.


web.xml

<servlet>
<servlet-name>REST</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>


My rest method

@POST
@Path("/users/{userId}/images")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadImage(@HeaderParam("securityToken") String securityToken, @PathParam("userId") Integer userId,
FormDataMultiPart form) {}


and the log message

09-Aug-2016 09:41:42.718 SEVERE [http-nio-8080-exec-10] com.sun.jersey.spi.container.ContainerRequest.getEntity A message body reader for Java class org.glassfish.jersey.media.multipart.FormDataMultiPart, and Java type class org.glassfish.jersey.media.multipart.FormDataMultiPart, and MIME media type multipart/form-data; boundary=myRandomBoundary12345 was not found.
The registered message body readers compatible with the MIME media type are:
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
com.sun.jersey.core.impl.provider.entity.EntityHolderReader
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General

Answer

With Jersey 2.x and a Servlet 3.x container, you don't need a web.xml deployment descriptor. For more details, check the Jersey documentation about deployment.


You could use the @FormDataParam annotation to bind the named body part(s) of a multipart/form-data request entity body to a resource method parameter, as exemplified below:

@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response upload(@FormDataParam("file") InputStream inputStream,
                       @FormDataParam("file") FormDataContentDisposition fileMetaData) {
    ...
}

To use multipart features you need to add the jersey-media-multipart module to your pom.xml file:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>2.23.1</version>
</dependency>

If you're not using Maven make sure to have all needed dependencies (see jersey-media-multipart) on the classpath. And don't forget to register the MultiPartFeature in your Application/ResourceConfig sub-class.

For more details, check the Jersey documentation about multipart requests.