File uploads with jersey-multipart?

14,466 views
Skip to first unread message

Michael Thaler

unread,
Aug 22, 2012, 4:57:56 PM8/22/12
to dropwiz...@googlegroups.com
Hi,

I'm having trouble doing file uploads to a Dropwizard service. I'm trying to use the jersey-multipart library version 1.13 with Dropwizard 0.5.1 (the Jersey version appears to match), and I have a method in a resource that looks like:

    @POST
    @Path("/material/{id}/content")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response postFileContent(@PathParam("id") String materialId,
                                    @FormDataParam("content") InputStream input,
                                    @FormDataParam("content") FormDataContentDisposition disposition) {

The problem is, when I try to hit this with an image file upload (containing a file upload with a name of "content"), I get a 415 and this error in the log:

ERROR [2012-08-22 20:49:52,423] com.sun.jersey.spi.container.ContainerRequest: A message body reader for Java class com.sun.jersey.multipart.FormDataMultiPart, and Java type class com.sun.jersey.multipart.FormDataMultiPart, and MIME media type multipart/form-data; boundary=----WebKitFormBoundarySQPbbpOKNA9xvoBW 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.json.impl.provider.entity.JSONArrayProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$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.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy

I'm guessing I need to add some kind of Provider to Jersey, but I've been trying a few ways of doing that in the service's initialize method and I can't figure out how to do it. Can anyone help?

Thanks,
--Mickey

Edward Ribeiro

unread,
Aug 22, 2012, 5:18:48 PM8/22/12
to dropwiz...@googlegroups.com
Hi,

Try this and tell me if it works:

import
com.sun.jersey.multipart.FormDataParam;

[...]

   @POST
    @Produces(TEXT_PLAIN)
    @Consumes(MULTIPART_FORM_DATA)
    public String uploadFile(@FormDataParam("file") final InputStream stream) throws Exception {

        String tempname = UUID.randomUUID().toString();
        final String outputPath = UPLOAD_DIR + File.separator + tempname;
        Files.copy(new InputSupplier<InputStream>() {
            @Override
            public InputStream getInput() throws IOException {
                return stream;                
            }
        }, new File(outputPath));

        return tempname;
    }

In addition to jersey-server, I am using the following package:

                <dependency>
                        <groupId>com.sun.jersey.contribs</groupId>
                        <artifactId>jersey-multipart</artifactId>
                        <version>1.8</version>
                </dependency>  
-----
Edward

Michael Thaler

unread,
Aug 22, 2012, 5:42:38 PM8/22/12
to dropwiz...@googlegroups.com
I got the same error as before, with that exact code. Something must be wrong with my environment?

Here's my dependencies from my pom.xml.

                <dependency>
            <groupId>com.yammer.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
            <version>0.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.yammer.dropwizard</groupId>
            <artifactId>dropwizard-db</artifactId>
            <version>0.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.yammer.dropwizard</groupId>
            <artifactId>dropwizard-testing</artifactId>
            <version>0.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.6.6</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-multipart</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.19</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
            <version>1.3.12</version>
        </dependency>

(I had been using version 1.13 of jersey-multipart, but I changed it to 1.8 to run your example code, which sadly didn't fix it.)

--Mickey

Edward Ribeiro

unread,
Aug 22, 2012, 5:46:16 PM8/22/12
to dropwiz...@googlegroups.com
Your pom.xml seems OK to me. And the code snippet I sent worked fine months ago.

I'll check it with dropwizard and get back the mailing list.

Edward

Adam Parrish

unread,
Aug 22, 2012, 7:00:18 PM8/22/12
to dropwiz...@googlegroups.com
Edward:

I am actively using this method signature for my upload feature:

@POST
    @Path("/uploadattachment")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Attachment uploadFile(
            @QueryParam("apiKey") String apiKey,
            @FormDataParam("file") InputStream uploadedInputStream,
            @FormDataParam("file") FormDataContentDisposition fileDetail) {

I have the following pom dependencies related to this:


        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-multipart</artifactId>
            <version>1.12</version>
        </dependency>


Not sure if there is a huge diff, but I am using 1.12 instead of 1.8. 

Edward Ribeiro

unread,
Aug 22, 2012, 8:40:57 PM8/22/12
to dropwiz...@googlegroups.com
Hi Adam,

I've incorporated file upload on a *pretty* basic dropwizard example that I keep up. It worked here. :) As the name implies, it is an unsorted collection of snippets and throwaway code I keep. 


You only need to check the "dropwizard-example" folder. I created a page called "upload-test.html" that points to localhost:8080 and allows the uploading of any file to "/tmp". Feel free to change this code as you like and play with it, and I suggest you to bump to newer versions of both dropwizard and jersey-multipart so that to check if it still works with updates. As far I can see, it has to do with the encoding type used in the client side. I had to put it explicitly in the HTML form, but you should be able to do so with cURL or wget. 

See if it helps. 

Edward

Adam Parrish

unread,
Aug 22, 2012, 9:35:05 PM8/22/12
to dropwiz...@googlegroups.com
Edward:

Looks to me like your code should work. I hope Michael figures out what was wrong with his. 

I need to do some dumping of some of my reusable code from my current code somewhere...just haven't had time time yet since it needs to be a bit less specific to the project to share it. 

Anyways thanks for sharing that!

-Adam 

Michael Thaler

unread,
Aug 23, 2012, 12:04:59 PM8/23/12
to dropwiz...@googlegroups.com
I got it working: I figured out which Provider I had to add to the environment.

env.addProvider(com.sun.jersey.multipart.impl.MultiPartReaderServerSide.class);

This fixes it. But why does yours work fine without doing this (including when I compile and run your example project)?

--Mickey

Pascal

unread,
Dec 13, 2012, 8:18:11 AM12/13/12
to dropwiz...@googlegroups.com
Hello,
I have the same problem...
 
Where did you register the MultiPart provider?
Where do I get that "env."?
 
Thanks,
Pascal

Kyle Boon

unread,
Dec 13, 2012, 10:42:23 AM12/13/12
to dropwiz...@googlegroups.com
The version of jersey multipart needs to be the same version of jersey that dropwizard is using. If you're using dropwizard 0.6.1 then you should have:


<dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-multipart</artifactId>
            <version>1.15</version>
        </dependency>

Hope that helps.

lessc...@googlemail.com

unread,
Jun 20, 2013, 5:34:13 AM6/20/13
to dropwiz...@googlegroups.com
I was having the same problem and solved that by adding mimepull-1.9.3.jar.

張祐維

unread,
Jul 26, 2013, 2:57:01 AM7/26/13
to dropwiz...@googlegroups.com
me,too

lessc...@googlemail.com於 2013年6月20日星期四UTC+8下午5時34分13秒寫道:

Sathish V

unread,
Sep 11, 2013, 2:09:35 PM9/11/13
to dropwiz...@googlegroups.com
- Adding 

env.addProvider(com.sun.jersey.multipart.impl.MultiPartReaderServerSide.class);

gave me Exception saying that Provider cannot be instanticated.So after adding

env.addProvider(MultiPartConfigProvider.class);
env.addProvider(com.sun.jersey.multipart.impl.MultiPartReaderServerSide.class);

Solved the issue and worked fine.

Thanks







 

Karla Hernández

unread,
Apr 3, 2014, 6:25:07 PM4/3/14
to dropwiz...@googlegroups.com
Hi guys,
I'm having a weird issue.
I added the mimepull dependency and multipart (same version of jersey bundle and multipart dependency). It works when I run the jar on my IDE (IntelliJ and Eclipse) but when I try to run it on my terminal (cmd) it throws the next error:

SEVERE: Missing dependency for method public void com.applicationserver.resources.ConfigurationResource.receiveFileImportTool(java.io.InputStream,java.lang.String) at parameter at index 0
WARN / 16:09:29.357 main unavailable
com.sun.jersey.spi.inject.Errors$ErrorMessagesException: null
        at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:771) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:766) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:488) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:318) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:609) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at javax.servlet.GenericServlet.init(GenericServlet.java:244) ~[agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:519) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:331) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:742) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:265) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:710) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:229) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:95) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.server.Server.doStart(Server.java:280) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:64) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.yammer.dropwizard.cli.ServerCommand.run(ServerCommand.java:48) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.yammer.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:39) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.yammer.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:58) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.yammer.dropwizard.cli.Cli.run(Cli.java:53) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
        at com.yammer.dropwizard.Service.run(Service.java:61) [agent-loader-1.0-SNAPSHOT-jar-with-dependencies.jar:na]
       .......
INFO o.q.xml.XMLSchedulingDataProcessor 16:09:29.627 main Parsing XML file: jobs.xml with systemId: jobs.xml

____________________________________________________________________

Do you have any idea of what could be happen here?

Dropwizard version : 0.6.2
Jersey : 1.17.1
Mimepull: 1.7
Multipart: 1.17.1

Thanks,
Karla

Carlo Barbara

unread,
Apr 3, 2014, 6:47:12 PM4/3/14
to dropwiz...@googlegroups.com

Sounds like a classpath issue. Are you running against the shaded jar?

Karla Hernández

unread,
Apr 3, 2014, 7:00:27 PM4/3/14
to dropwiz...@googlegroups.com
Nop... I'm using the Uber jar. 
Thanks,
Karla

Karla Hernández

unread,
Apr 23, 2014, 6:47:04 PM4/23/14
to dropwiz...@googlegroups.com
Hello all,
Finally I found why it was happening. I was using the [maven-assembly-plugin] in order to build the jar file. Every time when I tried to run the generated jar the error happens but when I change it with the [maven-shade-plugin] the issue was gone!
It make sense now!
Since I'm working in a module project I still have a lot of doubts regarding this.
What kind of implications are expected with this change?

Smallufo Huang

unread,
May 18, 2014, 12:29:23 PM5/18/14
to dropwiz...@googlegroups.com
In dropwizard 0.7

No matter one line
environment.jersey().register(MultiPartReaderServerSide.class);

or two lines :
environment.jersey().register(MultiPartConfigProvider.class);
environment.jersey().register(MultiPartReaderServerSide.class);

both not working … :(

ERROR [2014-05-19 00:23:53,014] com.sun.jersey.spi.inject.Errors: The following errors and warnings have been detected with resource and/or provider classes:
  SEVERE: Missing dependency for method public juno.api.ApiResult juno.api.resources.TestApi.uploadPicture(java.io.InputStream) at parameter at index 0
WARN  [2014-05-19 00:23:53,027] /api: unavailable

while TestApi.uploadPicture :
public ApiResult uploadPicture(
    @FormDataParam("file") @ApiParam(required = true) InputStream is
  ) {… }

pom version is 1.18.1

    <dependency>
      <groupId>com.sun.jersey.contribs</groupId>
      <artifactId>jersey-multipart</artifactId>
      <version>1.18.1</version>
    </dependency>

dependency:tree also show it is 1.18.1 included :
[INFO] +- com.sun.jersey.contribs:jersey-multipart:jar:1.18.1:compile
[INFO] |  +- org.jvnet.mimepull:mimepull:jar:1.9.3:compile
[INFO] |  \- com.sun.jersey:jersey-core:jar:1.18.1:compile


Any way to solve it ?

smallufo

unread,
May 19, 2014, 12:47:14 AM5/19/14
to dropwiz...@googlegroups.com
ok . I found the solution:

It lacks of 
  @Consumes(MediaType.MULTIPART_FORM_DATA)

Reply all
Reply to author
Forward
0 new messages