0

There is an existing project that uses Scalatra (2.6) and Swagger:

scalaMajorVersion = '2.12'
scalaVersion = "${scalaMajorVersion}.8"
scalatraVersion = "${scalaMajorVersion}:2.6.4"

compile "org.scalatra:scalatra-swagger_${scalatraVersion}"

I easily could add a new end point like:

  get ("/upload", op[String](  // op finally invokes apiOperation
    name = "Test method",
    params = List(
      query[Long]("id" -> "ID"),
      query[String]("loginName" -> "login name")
    ),
    authorizations = List(Permission.xxxxx.name)
  )) {
   ...
  }

but I cannot upload a file.

I expect to see a file selector button, but instead I see a single-line edit field.

(There are numerous things I'm uncertain about: form or file, [String] or [FileItem], which trait(s), what kind of initialization, etc.)

In the existing code I found a comment that someone could not get swagger to handle file upload. At the same time, I read that Scalatra and Swagger can do that, not all versions of them, but it looks like the version used in the project should be able to do that.

I could find code examples with yml/json interface definitions, but in the project there is no yml, only the apiOperation-based stuff.

Is there a working example using Scalatra 2.6, Swagger, and apiOperation?

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127

1 Answers1

0

I managed to get the file chooser (file selector, "Browse") button; there was no predefined constant (like DataType.String) for that. After I used DataType("File"), everything else just worked.

https://docs.swagger.io/spec.html says:

4.3.5 File

The File (case sensitive) is a special type used to denote file upload. Note that declaring a model with the name File may lead to various conflicts with third party tools and SHOULD be avoided.

When using File, the consumes field MUST be "multipart/form-data", and the paramType MUST be "form".

  post ("/uploadfile", op[String](  // op finally invokes apiOperation
    name = "Upload File",
    params = List(
      new Parameter(
        `name` = "kindaName",
        `description` = Some("kindaDescription2"),
        `type` = DataType("File"),            // <===== !!!!!!
        `notes` = Some("kindaNotes"),
        `paramType` = ParamType.Form,         // <===== !!
        `defaultValue` = None,
        `allowableValues` = AllowableValues.AnyValue,
        `required` = true
      )
    ),
    consumes = List("multipart/form-data"),   // <===== !!
...
)) {
    val file: FileItem = fileParams("kindaName") // exception if missing
    println("===========")
    println("file: " + file)
    println("name: " + file.getName + " size:"+file.getSize+" fieldName:"+file.getFieldName+ " ContentType:"+file.getContentType+" Charset:"+file.getCharset)
    println("====vvv====")
    io.copy(file.getInputStream, System.out)
    println("====^^^====")
    val file2: Option[FileItem] = fileParams.get("file123") // None if missing, and it is missing
    println("file2: " + file2)

PS the apiOperation stuff is called "annotations".

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127