Swagger UI - Uploading files

10,515 views
Skip to first unread message

Markus Jura

unread,
Nov 5, 2012, 10:42:19 AM11/5/12
to swagger-sw...@googlegroups.com
Hey guys,

how I can upload files as multipart/form-data over the swagger-ui. I do not see any element to select a file and upload it with "Try it out!".

I am using:
swagger-play2 scala 1.1.1

Thanks
Markus

Ayush Gupta

unread,
Nov 5, 2012, 10:44:18 AM11/5/12
to swagger-sw...@googlegroups.com
Is this what you're asking for? If it is, it should be pushed to swagger-ui in the next day or two.

-ayush

Lloyd

unread,
Nov 14, 2012, 10:47:46 PM11/14/12
to swagger-sw...@googlegroups.com
Hi, any progress with this ? At the moment the pull request is still outstanding.

Ayush Gupta

unread,
Nov 15, 2012, 12:44:03 AM11/15/12
to swagger-sw...@googlegroups.com
Sorry about the delay. This is pushed and a sample server side usage in Play 2 is here.

-ayush

vinai jeremy

unread,
Jan 25, 2013, 4:47:36 AM1/25/13
to swagger-sw...@googlegroups.com
Should it exist a java version of the server side ? I'm not using scala file.

tony tam

unread,
Jan 25, 2013, 1:31:18 PM1/25/13
to swagger-sw...@googlegroups.com
There will be a sample pushed for JAX-RS shortly, there are some challenges with input format, which will be addressed by this:


under "content type description".

tony tam

unread,
Jan 25, 2013, 11:43:16 PM1/25/13
to swagger-sw...@googlegroups.com
Hi, there's a jax-rs file upload sample here:


which requires the latest swagger-ui from here:


Note that you need to grab the pre-compiled ui source from the dist folder rather than downloads page, since github stopped that feature (sigh).

Alessio Dione

unread,
Apr 4, 2013, 5:04:19 AM4/4/13
to swagger-sw...@googlegroups.com

Hi all,
Did anyone tried the scala-jaxrs-fileupload example?
I downloaded and built the swagger-core 1.2 spec, used locally on my project and annotated a file upload service
as shown in the example "/uploadImage" found here "https://github.com/wordnik/swagger-core/blob/1.2.0-spec/samples/scala-jaxrs-fileupload/src/main/scala/com/wordnik/swagger/sample/resource/PetResource.scala"

However it's not working as expected, what I get in the Swagger-UI (cloned from the master branch) are text-areas instead of the browse files button:


I also tried annotating the service as shown in the other example (the one for play2 framework) found here: "https://github.com/wordnik/swagger-core/blob/be926c8d94d77dd61730b6a17b86efdb5a2ae275/samples/scala-play2/app/controllers/PetApiController.scala#L101".


It does get the browse button in Swagger-UI but the service signature will change and it's different from the scala-jaxrs example,
my attempts of mixing the two things failed. At least unless I change the service signature and existing implementation but that's not an option.



Any idea? Could anyone shed some light on it, please?
Thank you.

Alessio Dione

unread,
Apr 4, 2013, 7:03:36 AM4/4/13
to swagger-sw...@googlegroups.com
I forgot to mention that I changed the scala.version from 2.9.1-1 to 2.10.0 in the swagger-project POM
otherwise the code compiles but fails at runtime with:

apr 04, 2013 12:59:03 PM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
Grave: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NoSuchMethodError: scala.collection.JavaConverters$.asScalaSetConverter(Ljava/util/Set;)Lscala/collection/JavaConverters$AsScala;
    at com.wordnik.swagger.jaxrs.listing.ApiListingResource$.routes(ApiListing.scala:30)
    at com.wordnik.swagger.jaxrs.listing.ApiListing.resourceListing(ApiListing.scala:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)

tony tam

unread,
Apr 4, 2013, 10:48:25 AM4/4/13
to swagger-sw...@googlegroups.com
Howdy, the file upload definitely works fine, several folks (including us) us it in production.  Can you please try the main branch here:


Which will work out-of-the-box with the swagger-ui, which lives in this repo:


Please see that you can get the sample working OK then we can look at the 2.10.0 scala version.  The 1.2.2 version of swagger-core should be released tomorrow, and cross-built to scala 2.10.

Alessio Dione

unread,
Apr 5, 2013, 8:48:06 AM4/5/13
to swagger-sw...@googlegroups.com
Thanks Tony,
Actually the file-upload example works fine, I guess somewhere I have some bugs - either in the manual build of
swagger core part I done 2 weeks ago or in the swagger UI part customization we introduced...

So I tried to modify the example to check out if my case scenario is supported: adding some String parameters in the service signature:
  @POST
  @Path("/myUploadImage")
  @Consumes(Array(MediaType.MULTIPART_FORM_DATA))
  @ApiOperation(value = "uploads an image")
  def myUploadFile(
    @ApiParam(value = "tokenId") @FormDataParam("tokenId") tokenId: String,
    @ApiParam(value = "clientId") @FormDataParam("clientId") clientId: String,
    @ApiParam(value = "file to upload") @FormDataParam("file") inputStream: InputStream

    ) = {

    val msg = /*"Client ID: " + clientId + */", Token ID: " + tokenId //+ ", FileName: " + fileName
    val output = new com.wordnik.swagger.sample.model.ApiResponse(200, msg)
    Response.status(200).entity(output).build()
  }

However it turns out the String parameters are ignored and only the actual file is considered, this leads
to have the browse button in the UI (and in the generated JSON as well).
I checked the JerseyApiReader.scala class and found that other parameters are ignored by design,
can we consider the possibility of letting other parameters in the POST body beside the actual file?
Thanks.

tony tam

unread,
Apr 5, 2013, 11:28:44 AM4/5/13
to swagger-sw...@googlegroups.com
Got it--this has been fixed and pushed to master.  Note, you'll have to build & deploy swagger-jersey-jaxrs locally to pick it up (not in snapshots repo yet).

In your service, you would do this:

  @POST
  @Path("/uploadImage")
  @Consumes(Array(MediaType.MULTIPART_FORM_DATA))
  @ApiOperation(value = "uploads an image")
  def uploadFile(
    @ApiParam(value = "String to pass during submit") @FormDataParam("test") testString: String,
    @ApiParam(value = "file to upload") @FormDataParam("file") inputStream: InputStream,
    @ApiParam(value = "file detail") @FormDataParam("file") fileDetail: FormDataContentDisposition) = {
    println("testString: " + testString)
    val uploadedFileLocation = "./" + fileDetail.getFileName
    IOUtils.copy(inputStream, new FileOutputStream(uploadedFileLocation))
    val msg = "File uploaded to " + uploadedFileLocation + ", " + (new java.io.File(uploadedFileLocation)).length + " bytes"
    val output = new com.wordnik.swagger.sample.model.ApiResponse(200, msg)
    Response.status(200).entity(output).build()
  }

Note the param type for `testString`.  Grab the latest from swagger-ui/dist and you're good.

Post back with any issues!

Henning Groß

unread,
May 9, 2013, 10:43:26 AM5/9/13
to swagger-sw...@googlegroups.com
Hi!
I am trying to get it to work in java. I have the following method-signature:

    @POST
    @ApiOperation("upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @ApiParamsImplicit(@ApiParamImplicit(dataType = "file", name = "file", paramType = "body"))
    public Response uploadTranslation(@FormDataParam("file") InputStream file)
    {
        return null;
    }

This results in the following behaviour:

a) I get a file picker because of @ApiParamsImplicit(@ApiParamImplicit(dataType = "file", name = "file", paramType = "body"))
b) @FormDataParam("file") InputStream file results in an textInput
c) I get HTTP Status 415 - Unsupported Media Type when submitting the form

Can anyone help me get on track? Also Scala may be a real cool language but for broader compatibility it would be a little easyier to develop in pure Java. I tend to do that in libraries/apis.
Anyway: any help would be greatly appreciated. I need to document an api and the only problem right now is that I cannot get swagger to support a method that consumes multipart (one json-object and two files, one of them being required, the other not).

Regards!

tony tam

unread,
May 9, 2013, 9:09:05 PM5/9/13
to swagger-sw...@googlegroups.com
Hi, this was cross-posted to github issues, so you can see the response here:

Sébastien Lorber

unread,
Jul 16, 2013, 11:51:55 AM7/16/13
to swagger-sw...@googlegroups.com
Hi,

I've just upgraded from 1.2.0 to 1.2.5.

It does work better for me with:

  @POST
  @Produces({MediaType.APPLICATION_JSON})
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  @ApiOperation(value = "Upload a document", responseClass = "xxx.FileMetadata")
  @ApiErrors({
          ...
  })
  @Path("/")
  @ApiPublic
  @CrossOriginResourceSharing(allowAllOrigins = true, allowHeaders = {}, allowCredentials = true)
  public Response archive(
          @ApiParam(required = false, name = "title", value = "The title of the document") @Multipart(value = "title", required = false) String title,
          @ApiParam(required = false, name = "tag", value = "The tag of the document. Can pass multiple tags separated by | char") @Multipart(value = "tag", required = false) String tagsString,
          @ApiParam(required = true, name = "archive", value = "The file content") @Multipart(value = "archive") @NotNull Attachment attachment
  ) {
  // ......
}

Perhaps it is because I'm using CXF instead of Jersey?

The CXF Attachment / Multipart is not handled?

tony tam

unread,
Jul 16, 2013, 12:46:25 PM7/16/13
to swagger-sw...@googlegroups.com
Hi Sebastian,
yes, as you'll see here:


The source is not scanning CXF Attachments.  You can work around this by adding an implicit (non-associative) annotation in the operation.

Sébastien Lorber

unread,
Jul 17, 2013, 4:42:28 AM7/17/13
to swagger-sw...@googlegroups.com
Yes, I saw that by looking at the sources Jersey.

I tried many different implicit parameters, like

  @ApiParamsImplicit(@ApiParamImplicit(dataType = "file", name = "archive", paramType = "body"))

It didn't work but I guess it is because we didn't upgrade the UI yet. I'll upgrade it and see what happens.



By the way, I have some questions. 
-> name = "archive" -> Does this mean it is the multipart named "archive"?
-> how can I pass a header for that multipart "archive". I'd like to use a header "Content-Disposition: attachment; filename=myFileName" - This header/filename is required by the API
-> is there any special support for this Content-Disposition header, so that this doesn't show a form on which the user should write "attachment; filename=xxx.jpg", and that the user could simply write the name of the file
-> as we select a file through a select file input, is there automatically the header applied to that multipart "Content-Disposition: form-data; name="archive"; filename="toto.jpg". This is normally handled by the browsers when using a form file upload.


Thanks
Reply all
Reply to author
Forward
0 new messages