Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Multipart Request with JSON #820

Closed
jposes22 opened this issue Aug 9, 2020 · 1 comment
Closed

Multipart Request with JSON #820

jposes22 opened this issue Aug 9, 2020 · 1 comment

Comments

@jposes22
Copy link

jposes22 commented Aug 9, 2020

Describe the bug

  • I try to make a simple request with multipart and JSON object but doesn't generate the right request.

An example of StackOverflow:
https://stackoverflow.com/a/25183266/4693765

To Reproduce
Steps to reproduce the behavior:

  • Spring boot 2.2.5.RELEASE
  • Spring doc 1.4.4
  • Kotlin project with:
springdoc-openapi-ui
springdoc-openapi-data-rest
springdoc-openapi-security
springdoc-openapi-kotlin

Rest controller:

 @PostMapping("test",consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
   fun saveDocu2ment(@RequestPart(value = "file",required = true) file: MultipartFile,
                     @RequestPart(required = true)  type:MailDto) {
    }

Open Api JSON

  "paths": {
    "/api/v2/mail/test": {
      "post": {
        "tags": [
          "mail-rest-controller-v-2"
        ],
        "operationId": "saveDocu2ment",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "type": {
                    "$ref": "#/components/schemas/MailDto"
                  }
                }

Request when execute with swagger-ui:
curl -X POST "http://localhost:8080/api/v2/mail/test" -H "accept: */*" -H "Content-Type: multipart/form-data" -F "type={ "authorizationToken": "string", "to": [ "string" ], "sender": "string", "subject": "string", "bodyText": "string", "files": [ "string" ] }" -F "file=@img_payment_success.png;type=image/png"

Screenshots
Image of example request
image

Additional context
An error response of spring boot (oviusly error):
ERROR 3108 --- [nio-8080-exec-1] e.d.s.base.BaseAdviceRestController : Content type 'application/octet-stream' not supported

@bnasslahsen
Copy link
Collaborator

@jposes22,

This is not a springdoc issue: springdoc-openapi is built on top of swagger-api/swagger-ui and spring-boot.
springdoc-openapi helps generating the OpenAPI spec. And you are not reporting any inconsitency about that.

The correct code, for your sample is:

@PostMapping(value = "/test", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
@RequestBody(content = @Content(encoding = @Encoding(name = "personDTO", contentType = "application/json")))
public ResponseEntity<Void> saveDocu2ment(
		@RequestPart(value = "personDTO")  final PersonDTO personDTO,
		@RequestPart(value = "file")  final MultipartFile file) {
	return null;
}

Which produces the following OpenAPI description:

openapi: 3.0.1
info:
  title: OpenAPI definition
  version: v0
servers:
  - url: 'http://localhost:8080'
    description: Generated server url
paths:
  /test:
    post:
      tags:
        - hello-controller
      operationId: saveDocu2ment
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                personDTO:
                  $ref: '#/components/schemas/PersonDTO'
                file:
                  type: string
                  format: binary
            encoding:
              personDTO:
                contentType: application/json
      responses:
        '200':
          description: OK
components:
  schemas:
    PersonDTO:
      type: object
      properties:
        email:
          type: string
        firstName:
          type: string
        lastName:
          type: string

Unfortunately, swagger-ui doesn't handle yet the support of the encoding attribute.

As discussed here #396, there is a workaround is to use the type binary for the other parts: (swagger-ui scans for the file extension to add the type of the request part).

Here a working sample code: The first parameter content should be in a file (with .json extension)

@PostMapping(value = "/test", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
public ResponseEntity<Void> saveDocu2ment(
		@RequestPart(value = "personDTO") @Parameter(schema =@Schema(type = "string", format = "binary")) final PersonDTO personDTO,
		@RequestPart(value = "file")  final MultipartFile file) {
	return null;
}

@springdoc springdoc locked as resolved and limited conversation to collaborators Oct 25, 2021
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants