Image upload with Swagger UI in Java

3,351 views
Skip to first unread message

phil

unread,
Mar 6, 2014, 8:59:31 AM3/6/14
to swagger-sw...@googlegroups.com
Hi everyone!

Swagger is an awesome tool for easily creating an API documentation. But I've got an issue with image uploads from the Swagger UI.

The Swagger UI demo for the image upload is here:
http://petstore.swagger.wordnik.com/#!/pet/uploadFile_post_8

The resource file for that demo is either the plain Scala or the Play 2 one:
https://github.com/wordnik/swagger-core/blob/master/samples/scala-jaxrs-fileupload/src/main/scala/com/wordnik/swagger/sample/resource/PetResource.scala
https://github.com/wordnik/swagger-core/blob/master/samples/scala-play2/app/controllers/PetApiController.scala

One is using the @ApiImplicitParams annotation, the other isn't.

I'm developing in Java, so I looked for a corresponding example for Jersey or JaxRS:
https://github.com/wordnik/swagger-core/blob/master/samples/java-jaxrs/src/main/java/com/wordnik/swagger/sample/resource/PetResource.java
https://github.com/wordnik/swagger-core/blob/master/samples/java-jersey2/src/main/java/com/wordnik/swagger/sample/resource/PetResource.java

Neither of the two has a method for image upload. I tried to adapt the code from the Scala examples, but didn't get it to work.

My Code is like this:

    @POST
    @Path( "images" )
    @Produces( MediaType.APPLICATION_JSON )
    @Consumes( MediaType.MULTIPART_FORM_DATA )
    @ApiOperation(value = "Create a new image (Multipart)", notes = "<short explanation>")
    public Response createNewImage(
        @ApiParam( value = "Application name", required = true ) @PathParam( "appName" ) String appName,
        @FormDataParam( "apiKey" ) String apiKey,
        @FormDataParam( "file name" ) String fileName,
        @FormDataParam( "file" ) InputStream uploadedInputStream )
    {...}

This code works fine with curl like this:
curl -v -F "file=@googlelogo.png" -F "apiKey=123" http://localhost:8080/path/MyApp/data/images

But it doesn't work with the Swagger UI "Try now!". When using that, I get this error:
    java.lang.NullPointerException
        at com.sun.jersey.multipart.impl.MultiPartReaderClientSide.unquoteMediaTypeParameters(MultiPartReaderClientSide.java:227)

Also, when trying to document the other FormDataParams with @ApiParam it results in 500 Internal Server Errors (don't have the stack trace at hand now - this is just of minor importance).

I'm using swagger-jersey-jaxrs_2.10 version 1.3.1.

Regarding the topic I read:
https://groups.google.com/forum/#!topic/swagger-swaggersocket/xJiG1etE3ns
https://github.com/wordnik/swagger-core/issues/184#issuecomment-17689042
But trying out what was done there didn't help.

-> If someone could help me with my code snippet or maybe even create an image upload example for the pet store in java for the greater good, that would be awesome!

Ron

unread,
Mar 6, 2014, 9:12:35 AM3/6/14
to swagger-sw...@googlegroups.com
Funny, I'm just working on rewriting the Java samples for Swagger and got to the file upload part as well. Unfortunately, since I'm not done, I don't have an answer to give you yet, but Tony may be able to comment a bit later.

Just to make sure - You're using Jersey, right? Not any other JAX-RS implementation. I'm assuming that since you referred to @FormDataParam which is a Jersey annotation as there appear to be no standard way to control it using 'pure' JAX-RS (though you can write an implementation that would be cross-implementation).


--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Message has been deleted

phil

unread,
Mar 6, 2014, 11:05:41 AM3/6/14
to swagger-sw...@googlegroups.com
Awesome! And thanks for the quick reply. I'm looking forward to see the sample code.

Yes, I'm using Jersey - swagger-jersey-jaxrs_2.10 version 1.3.1
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Ron

unread,
Mar 6, 2014, 11:21:21 AM3/6/14
to swagger-sw...@googlegroups.com
As for the internal server error, that's actually likely to have nothing to do with Swagger.
Check the documentation for @FormDataParam - https://jersey.java.net/nonav/apidocs/1.10/contribs/jersey-multipart/com/sun/jersey/multipart/FormDataParam.html


To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

phil

unread,
Mar 10, 2014, 7:07:04 AM3/10/14
to swagger-sw...@googlegroups.com
Ok thanks, I'll have a look at that.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

phil

unread,
May 30, 2014, 7:10:33 AM5/30/14
to swagger-sw...@googlegroups.com
Hi, it's me again. It's a while ago since I created this thread, but only now I had the time to get back to it.

You pointed me to the Jersey documentation, but I'm not sure what to look for. I added a parameter for the content disposition, but that didn't help. I inspected the error in more detail, the NullPointerException at MultiPartReaderClientSide.unquoteMediaTypeParameters(...).
When doing a request with cURL, the mediaType parameter is for example: "multipart/form-data; boundary=----------------------------02a402622d7b" and parameters parameter: "[boundary]" (without the quotes). With cURL everything works fine.
When doing a request with Swagger (try out), the mediaType parameter is for example: "multipart/form-data; charset=UTF-8" and the same parameters parameter.
So it seems that Swagger doesn't send a boundary. Is this meant to be that way?

Thanks in advance!


Am Donnerstag, 6. März 2014 17:21:21 UTC+1 schrieb Ron R:
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

tony tam

unread,
May 30, 2014, 9:49:21 AM5/30/14
to swagger-sw...@googlegroups.com
HI, what version of the UI are you using?  We did have a bug where the boundary was not well formed--that was addressed in the last UI release.

phil

unread,
May 30, 2014, 10:07:42 AM5/30/14
to swagger-sw...@googlegroups.com
<dependency>
    <groupId>com.wordnik</groupId>
    <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
    <version>1.3.1</version>
</dependency>

tony tam

unread,
May 30, 2014, 10:09:08 AM5/30/14
to swagger-sw...@googlegroups.com
Hi, first, that's a very old version, suggest you get up to 1.3.5.  Next, the issue was in the swagger-ui code, not the back end.  Can you please look in your swagger-ui.js file for a version at the top?  You should have this:

// swagger-ui.js
// version 2.0.17

phil

unread,
May 30, 2014, 10:52:13 AM5/30/14
to swagger-sw...@googlegroups.com
I'm getting exceptions from Spring when starting the server when setting swagger-jersey-jaxrs_2.10 to version 1.3.5. Could that originate from dependencies being old versions?
swagger-ui.js didn't have any version numbers on top, so I guess it was a very old one as well. I replaced the whole folder with the dist folder from github, so now it's 2.0.17.

There's still no boundary though. Maybe my annotations are wrong? Ron said something about the @FormDataParam.


@POST
    @Path( "images" )
    @Produces( MediaType.APPLICATION_JSON )
    @Consumes( MediaType.MULTIPART_FORM_DATA )
    @ApiOperation(value = "Upload an image (Multipart)", notes = "<short explanation>")
    public Response uploadImage(

        @ApiParam( value = "Application name", required = true ) @PathParam( "appName" ) String appName,
        @FormDataParam( "apiKey" ) String apiKey,
        @FormDataParam( "image name" ) String imageName,
        @FormDataParam( "image" ) InputStream uploadedInputStream,
        @FormDataParam( "image" ) FormDataContentDisposition imageDetails )
    {...}

phil

unread,
Jun 2, 2014, 5:12:54 AM6/2/14
to swagger-sw...@googlegroups.com
Okay so I updated to version 1.3.5. To do that I had to change two things:
1) @ApiOperation (authorization = "Xy", <others>) to @Authorization (value="Xy") @ApiOperation(<others>).
2) A Custom SwaggerSchemaConverter overrides the "read" method and had a wrong method signature after updating - had to add a Map<String,String> and also change all types to Scala types.

Now the project compiles and runs, but the initial error still exists: When trying to upload an image with Swagger UI there's still a NullPointerException in MultiPartReaderClientSide.unquoteMediaTypeParameters(...) which still seems to originate in a missing of a boundary.

When I started this thread Ron said he was working on image upload examples for Java. I'm still highly interested in seeing them as I'm sure they'd help me a lot :) .

https://github.com/wordnik/swagger-core/tree/master/samples/java-jersey2/src/main/java/com/wordnik/swagger/sample/resource

Ron

unread,
Jun 10, 2014, 7:30:22 AM6/10/14
to swagger-sw...@googlegroups.com
Hi Phil,

I apologize but I had to put that on hold to deal with other things.
However, if the file upload doesn't work, I'm not sure it relates to Swagger at all.

What happens if you use a general purpose REST client?
What happens if you disable Swagger from your application?
What's the full stack trace of the error?


To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages