Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey: MessageBodyReader not found for media type=multipart/form-data

Tags:

java

jersey

I have found a few questions like this on SO already but none of them seemed to address my particular problem, and I have been unable to find a solution on my own.

Here is the error I'm getting:

Caused by: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=multipart/form-data; boundary=----WebKitFormBoundaryHWk1XUaeu7pEiDth, type=class org.glassfish.jersey.media.multipart.FormDataMultiPart, genericType=class org.glassfish.jersey.media.multipart.FormDataMultiPart.

I am sending this through a jQuery AJAX request that looks like this:

$('#upload-image-form').on('submit', function(e) {
    e.preventDefault();
    var data = new FormData(this);
    $.ajax({
        url: url,
        method: 'POST',
        contentType: false,
        processData: false,
        data: data,
    }).done(function(data) {
        console.log(data);
    }).fail(function(res, status) {
        onError(res, status, 'Image upload failed');
    });
});

And this is my Java endpoint:

@POST
@Path("/{userId}")
@Consumes("multipart/form-data")
public Response createGraphic(
   @PathParam("userId") int userId,
   FormDataMultiPart multiPartFormData) { ... }

I have seen a few people have luck with changing the parameter of the endpoint method to use @FormDataParam instead of FormDataMultiPart (as seen here), but I cannot edit the Java class, so I must use it how it is above.

My pom.xml has the following dependencies:

<dependency>
    <groupId>org.jvnet</groupId>
    <artifactId>mimepull</artifactId>
    <version>1.6</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>2.12</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>2.12</version>
</dependency>

web.xml

<servlet>
   <servlet-name>Jersey</servlet-name>
   <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
   <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>my.package</param-value>
   </init-param>
   <load-on-startup>5</load-on-startup>
</servlet>

<servlet-mapping>
   <servlet-name>Jersey</servlet-name>
   <url-pattern>/api/*</url-pattern>
</servlet-mapping>

The only other thing I was able to dig up was to register the MultiPartFeature using a ResourceConfig; however, the project I'm working with does not have any Application classes or any class that extends ResourceConfig (it's a WAR that's deployed to Tomcat, so no main class).

Is there any other configuration that needs to be done? I'm stumped as to why this is not working.

like image 399
gpanders Avatar asked Oct 30 '22 23:10

gpanders


1 Answers

The MultiPartFeature has the required reader and writer. But you still need to register the feature. As you've mentioned, you will often see it's registration in an Application/ResourceConfig subclass. But in a web.xml, you can simply add it to the list of classes to add as provider. You can do that by adding an <init-param> to the servlet configuration, i.e.

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
        org.glassfish.jersey.media.multipart.MultiPartFeature,
        some.other.Provider
    </param-value>
</init-param>

As you can see in the example, if you need to register any other providers/features, you comma-delimit the class names.

like image 86
Paul Samsotha Avatar answered Nov 15 '22 05:11

Paul Samsotha