[BUG] [jaxrs-jersey] [java] [jersey] Generated API interface treats multipart arrays as a single file
Created by: itaru2622
Bug Report Checklist
-
Have you provided a full/minimal spec to reproduce the issue? -
Have you validated the input using an OpenAPI validator (example)? -
Have you tested with the latest master to confirm the issuue still exists? -
Have you search 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
Generated API interface for multipart arrays contains a single of InputStream and FormDataContentDisposition, instead of a list of those.
openapi-generator version
version 4.3.1 and official docker image openapitools/openapi-generator:cli-4.3.x pulled from https://hub.docker.com/r/openapitools/openapi-generator/
OpenAPI declaration file content or url
Generation Details
wget -O /tmp/form-multipart-binary-array.yaml https://raw.githubusercontent.com/OpenAPITools/openapi-generator/master/modules/openapi-generator/src/test/resources/3_0/form-multipart-binary-array.yaml
docker run -it -v /tmp:/tmp openapitools/openapi-generator:cli-4.3.x generate -g jaxrs-jersey -i /tmp/form-multipart-binary-array.yaml -o /tmp/out
cat /tmp/out/src/main/java/org/openapitools/api/impl/MultipartArrayApiServiceImpl.java | grep multipartArray
Steps to reproduce
Generate MultipartApi interface as listed above. Both multipartArray and multipartSingle methods contains a single of { InputStream, FormDataContentDisposition }
Related issues/PRs
Issue #3139 (closed) and PR #4616 (already merged).
Issue #3139 (closed) is occurred in spring and this is almost same issue occurred in jaxrs-jersey.
Suggest a fix
The following template files have no array, as described bellow snippets:
JavaJaxRS/formParams.mustache JavaJaxRS/serviceFormParams.mustache
@FormDataParam("{{baseName}}") InputStream {{paramName}}InputStream,
@FormDataParam("{{baseName}}") FormDataContentDisposition {{paramName}}Detail
There are following three choices to fix, according to stackoverflow.com and other sites. cf. https://stackoverflow.com/questions/56954122/multiple-files-upload-in-a-rest-service-using-jersey
Choice B and C could fix this issue but 'Choice A' may not. Some may prefer 'Choice C' but other may prefer 'Choice B' !?
choice A) simplest but FAILED in communication test.
- as described following snippets, just appending 'List' in multipartArray case.
- when I tested this choice in real communication, results are:
- multipartSingle case: passed.
- multipartArray case: failed. ApiServiceImpl cannot get file content because instance of
List<InputStream>
is always null . It needs some further investigation to find out reason.
{{^isListContainer}}
@FormDataParam("{{baseName}}") InputStream {{paramName}}InputStream,
@FormDataParam("{{baseName}}") FormDataContentDisposition {{paramName}}Detail
{{/isListContainer}}
{{#isListContainer}}
@FormDataParam("{{baseName}}") List<InputStream> {{paramName}}InputStream,
@FormDataParam("{{baseName}}") List<FormDataContentDisposition> {{paramName}}Detail
{{/isListContainer}}
choice B) keeping backward compatibility, but ugly in coding.
- Keep original template in multipartSingle case, and involve
List<FormDataBodyPart>
in multipartArray case as described in following snippets. - This choice enables users to keep using their ApiServiceImpl.java without any modification as far as multipartSingle case.
{{^isListContainer}}
@FormDataParam("{{baseName}}") InputStream {{paramName}}InputStream,
@FormDataParam("{{baseName}}") FormDataContentDisposition {{paramName}}Detail
{{/isListContainer}}
{{#isListContainer}}
@FormDataParam("{{baseName}}") List<FormDataBodyPart> {{paramName}}Bodypart
{{/isListContainer}}
- FormDataBodyPart is org.glassfish.jersey.media.multipart.FormDataBodyPart
choice C) breaking backward compatibility, but smarter.
- Always using FormDataBodyPart, and appending List in multipartArray case.
- Users may need little change in their ApiServiceImpl.java .
{{^isListContainer}}
@FormDataParam("{{baseName}}") FormDataBodyPart {{paramName}}Bodypart
{{/isListContainer}}
{{#isListContainer}}
@FormDataParam("{{baseName}}") List<FormDataBodyPart> {{paramName}}Bodypart
{{/isListContainer}}