Search code examples
javajerseytomcat7jax-rsmultipartform-data

Jersey 2 injection source for multipart formdata


I had a method:

@POST
@Consumes("multipart/form-data")
@Produces( {"text/xml"})
public Response processForm(
    @FormDataParam("myparam") InputStream is,
    @FormDataParam("myparam") FormDataContentDisposition detail)

which worked fine with Jersey 1.x.

I'm upgrading to 2.0 m11.

Now I get the following error:

12/01/2013 11:15:04 AM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.0-m11 2012-12-21 12:34:15...
12/01/2013 11:15:04 AM org.glassfish.jersey.internal.Errors processErrors
SEVERE: The following errors and warnings have been detected:
WARNING: No injection source found for a parameter of type public javax.ws.rs.core.Response com.plutext.FileUpload.processForm(java.io.InputStream,org.glassfish
.jersey.media.multipart.FormDataContentDisposition) at index 0.

I found http://java.net/jira/browse/JERSEY-1413 and commit http://java.net/projects/jersey/lists/commits/archive/2012-09/message/126 which seems relevant, but its not obvious to me what to do to fix the problem.

UPDATED

I made a servlet, which runs in Tomcat before org.glassfish.jersey.server.ApplicationHandler initialize:

public class Jersey2Init extends HttpServlet {

    private static final Logger jul = Logger.getLogger(Jersey2Init.class
        .getName());

    static {    
        System.out.println("\n\nrunning Jersey2Init\n\n");

        final ResourceConfig resourceConfig1 = new ResourceConfig(XFormService.class);
        resourceConfig1.registerInstances(new LoggingFilter(jul, true));
        resourceConfig1.register(MultiPartFeature.class);       

        final ResourceConfig resourceConfig2 = new ResourceConfig(AssembleService.class);
        resourceConfig2.registerInstances(new LoggingFilter(jul, true));
        resourceConfig2.register(MultiPartFeature.class);       
    }
}

It is definitely running first:

INFO: Deploying web application archive C:\Java\apache-tomcat-7.0.29\webapps\Foo-Services.war


running Jersey2Init


18/01/2013 9:09:51 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.0-m11 2012-12-21 12:34:15...
18/01/2013 9:09:52 PM org.glassfish.jersey.internal.Errors processErrors
SEVERE: The following errors and warnings have been detected:

But I still get the same error.


Solution

  • You need to enable MultiPart feature on your application. Enabling this feature injects necessary message body readers, writers to your Jersey 2 application. Here is how you register them:

    On the server-side (http-server):

    final ResourceConfig resourceConfig = new ResourceConfig(MultiPartResource.class);
    resourceConfig.register(MultiPartFeature.class);
    

    On the server-side (servlet deployment):

    import org.glassfish.jersey.filter.LoggingFilter;
    import org.glassfish.jersey.media.multipart.MultiPartFeature;
    
    import javax.ws.rs.core.Application;
    import java.util.HashSet;
    import java.util.Set;
    
    public class MyApplication extends Application {
        @Override
        public Set<Class<?>> getClasses() {
            final Set<Class<?>> classes = new HashSet<Class<?>>();
            // register resources and features
            classes.add(MultiPartFeature.class);
            classes.add(MultiPartResource.class);
            classes.add(LoggingFilter.class);
            return classes;
        }
    }
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
        <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
        <servlet>
            <servlet-name>Jersey Servlet</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>javax.ws.rs.Application</param-name>
                <param-value>com.aruld.jersey.multipart.MyApplication</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey Servlet</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    </web-app>
    

    On the client-side:

    final ClientConfig clientConfig = new ClientConfig();
    clientConfig.register(MultiPartFeature.class);
    Client client = ClientFactory.newClient(clientConfig);
    

    I put together an end-to-end Jersey 2 MultiPart sample in Github here.