Skip to content

[Java][Spring][BUG] Code for multipart not working #1646

@balzmo

Description

@balzmo
Description

When generating multipart interfaces, the interface code is not working for Spring with Jersey:

  • A mixture of @RequestPart and @RequestParam is used to describe the multipart, while only @RequestPart is recognized by the framework at runtime
  • The parameter name for binary parts is not taken from the specification, instead "file" is used
  • The flag "required" is ignored for binary parts

Actual result:

ResponseEntity<Void> upload(
    @ApiParam(value = "", required=true, defaultValue="null")
    @RequestParam(value="meta", required=true)  MetaData meta,
    @ApiParam(value = "file detail") @Valid
    @RequestPart("file") MultipartFile document) {

This code line leads to the following error on invocation:

Failed to convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile'
to required type 'demo.oagen.fileupload.spring.gen.MetaData'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile'
to required type 'demo.oagen.fileupload.spring.gen.MetaData':
no matching editors or conversion strategy found

Expected result:

ResponseEntity<Void> upload(
    @ApiParam(value = "", required=true, defaultValue="null")
    @RequestPart(value="meta", required=true)  MetaData meta,
    @ApiParam(value = "file detail") @Valid
    @RequestPart(value = "document", required=true) MultipartFile document) {
openapi-generator version

3.3.4

OpenAPI declaration file content or url

Example interface extract, full example see attached:

      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                meta:
                  $ref: "#/components/schemas/MetaData"
                document:
                  type: string
                  format: binary
              required:
                - meta
                - document
Command line used for generation

Maven code:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>3.3.4</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/demo.yaml</inputSpec>
                <generatorName>spring</generatorName>
                <output>${project.basedir}/target</output>
                <apiPackage>demo.oagen.fileupload.spring.gen</apiPackage>
                <modelPackage>demo.oagen.fileupload.spring.gen</modelPackage>
                <configOptions>
                    <sourceFolder>/generated-sources/java</sourceFolder>
                    <basePackage>demo.oagen.fileupload.spring.gen</basePackage>
                    <configPackage>demo.oagen.fileupload.spring.gen.config</configPackage>
                    <useTags>true</useTags>
                    <interfaceOnly>true</interfaceOnly>
                </configOptions>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.openapitools</groupId>
            <artifactId>openapi-generator-maven-plugin</artifactId>
            <version>3.3.4</version>
            <type>maven-plugin</type>
        </dependency>
    </dependencies>
</plugin>
Steps to reproduce

Execute code generation via Maven on example project attached.
oagen-fileupload-spring-demo.zip

Send the following request:

POST http://127.0.0.1:8080/upload HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: multipart/form-data; boundary="----=_Part_17_744410358.1544434419692"
MIME-Version: 1.0
Content-Length: 82439
Host: 127.0.0.1:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_162)


------=_Part_17_744410358.1544434419692
Content-Type: application/json; name=demo-meta.json
Content-Transfer-Encoding: binary
Content-Disposition: form-data; name="meta"; filename="demo-meta.json"

{
	"fileName": "testfile.pdf",
	"comment": "hello"
}
------=_Part_17_744410358.1544434419692
Content-Type: application/pdf; name=Test.pdf
Content-Transfer-Encoding: binary
Content-Disposition: form-data; name="document"; filename="Test.pdf"

(binary content here)

Note: The example pom.xml contains a workaround for replacing the concerned code line with the correct code.

Suggest a fix
  • Use only @RequestParam for all parts of the multipart request body
  • Consider the property name for binary parts
  • Consider the "required" flag for binary parts

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions