-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator?
- Have you tested with the latest master to confirm the issue still exists?
- Have you searched for related issues/PRs?
- What's the actual output vs expected output?
- [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
The java-spring generator allows users to generate Spring Boot controllers & service interfaces for both reactive (Spring WebFlux) or non-reactive (Spring MVC) servers.
In PR #6993 @bit-factor addressed an issue with the parameter type used when generating code to use multipart-form-data upload for Spring WebFlux. However, it looks like the solution, or the current state of the support, is incorrectly generating the wrong parameter type for OpenAPI specs are uploading a single file vs multiple files.
For single file uploads the java-spring generator is using the parameter type Flux<Part>
, which is ok but may be technically incorrect as this supports uploading more than a single file. However, for multiple file uploads the generator is using the parameter type of List<Flux<Part>>
which is incorrect.
Actually using an endpoint with the List<Flux<Part>>
parameter type generates a 415 UNSUPPORTED_MEDIA_TYPE
HTTP status when attempting to upload a file
{
"timestamp": "2025-07-14T21:03:19.192+00:00",
"path": "/upload",
"status": 415,
"error": "Unsupported Media Type",
"requestId": "83f6588a-1"
}
Additionally the generated code is counter to some of the example articles referenced in the original issue which state:
N.B: Remember that,
- To upload multiple file you must have to use
Flux<FilePart>
.- To upload single file you have to use
Mono<FilePart>
orFilePart
.Mono<MultiValueMap<String, Part>>
can be used for both case. But in that case you have to find out the
FilePart(s)
from the map bykey
.
openapi-generator version
version 7.14.0
OpenAPI declaration file content or url
For reference there are two different example specs for uploading a single file with multipart-form-data versus uploading multiple files
The main difference is that the schema for single file upload looks like
fileName:
type: string
format: binary
while multiple file upload looks like
fileName:
type: array
items:
type: string
format: binary
Generation Details
java -jar openapi-generator-cli.jar generate -g spring --library spring-boot --additional-properties=reactive=true -i openapi-spec.yaml -o src
Steps to reproduce
- Generate a Java Spring service using the following openapi-spec:
openapi: 3.0.1
info:
title: webflux-file-upload
description: Test service for multiple file upload with webflux
version: 0.0.1
paths:
/upload:
post:
summary: uploads a file
operationId: uploadFile
tags:
- upload
description: upload a file
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
filename:
type: array
items:
type: string
format: binary
responses:
201:
description: upload was successful
use the command line java -jar openapi-generator-cli.jar generate -g spring --library spring-boot --additional-properties=reactive=true -i openapi-spec.yaml -o src
- Compile the project generated in the
src
directory - Run the web service
- Attempt to upload a file or files using the
/upload
endpoint:
curl -X POST http://localhost:8080/upload -H 'Content-Type: multipart/form-data' -F filename=@"pom.xml"
Related issues/PRs
Suggest a fix
The relevant part of the templates which are including List<Flux<Part>>
look like:
{{#isFile}}{{#isArray}}List<{{/isArray}}{{#reactive}}Flux<Part>{{/reactive}}{{^reactive}}{{#isFormParam}}MultipartFile{{/isFormParam}}{{^isFormParam}}{{>optionalDataType}}{{/isFormParam}}{{/reactive}}{{#isArray}}>{{/isArray}}{{/isFile}}
I think that they should look more like:
{{#isFile}}{{#reactive}}{{#isArray}}Flux<{{/isArray}}Part{{#isArray}}>{{/isArray}}{{/reactive}}{{^reactive}}{{#isArray}}List<{{/isArray}}{{#isFormParam}}MultipartFile{{/isFormParam}}{{^isFormParam}}{{>optionalDataType}}{{/isFormParam}}{{#isArray}}>{{/isArray}}{{/reactive}}{{/isFile}}
This would use Flux<Part>
when the file parameters is reactive and is an array, otherwise it would use Part
. For non-reactive parameters the template would continue to use List
for arrays.