Reputation: 932
I'm trying to upload array of .pdf
/.docx
/.whatever
.
As per Swagger's docs they do enable sending an array of files. I just don't know how to tell Swagger-UI
to create that kind of request.
I have following dependencies for Swagger
(not sure whether this refers to OAS2
or OAS3
):
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
Here is my SwaggerConfig
class (placed within package of main
Spring Boot function):
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket swaggerPlugin() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.paths(PathSelectors.any())
.apis(RequestHandlerSelectors.any())
.build()
.securitySchemes(Arrays.asList(apiKey()))
.securityContexts(Arrays.asList(securityContext()))
.apiInfo(metaData());
}
private ApiInfo metaData() {
return new ApiInfoBuilder()
.title("Spring Boot REST API - Garbage Collectors App")
.description("*")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build();
}
@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder().scopeSeparator(",")
.additionalQueryStringParams(null)
.useBasicAuthenticationWithAccessCodeGrant(false).build();
}
private ApiKey apiKey() {
return new ApiKey("apiKey", "Authorization", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth())
.forPaths(PathSelectors.any()).build();
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope(
"global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Arrays.asList(new SecurityReference("apiKey",
authorizationScopes));
}
@Bean
UiConfiguration uiConfig() {
return UiConfigurationBuilder.builder()
.deepLinking(true)
.displayOperationId(false)
.defaultModelsExpandDepth(1)
.defaultModelExpandDepth(1)
.defaultModelRendering(ModelRendering.EXAMPLE)
.displayRequestDuration(true)
.docExpansion(DocExpansion.NONE)
.filter(false)
.maxDisplayedTags(null)
.operationsSorter(OperationsSorter.ALPHA)
.showExtensions(false)
.tagsSorter(TagsSorter.ALPHA)
.supportedSubmitMethods(UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS)
.validatorUrl(null)
.build();
}
}
Also, here is the controller I'm using:
@ApiParam(allowMultiple=true)
@RequestMapping(value = "/send/email", consumes = {"multipart/form-data"}, method = RequestMethod.POST)
public String sendEmail(@RequestParam("attachments") MultipartFile[] attachments) throws IOException {
System.out.println(attachments.length);
return "test";
}
I'm able to pick an array of files from file system:
But after sending request I get following error:
{
"timestamp": "2020-12-22T18:29:29.578+00:00",
"status": 400,
"error": "Bad Request",
"trace": "org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'attachments' is not present org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:199)\r\n\tat org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:114)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat
}
On the other hand single MultipartFile
upload and any number of individually pre-determined MultipartFile can be uploaded without any problems.
What did I else tried:
-going over google inside and out
-reading the docs: In here I can see that they made a fix on the issue but I still don't know how to tell Swagger-UI to make request which I'm specifying on server-side, no matter which dependency version I user.
-try to set application.ymal
like so:
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
orderId:
type: integer
userId:
type: integer
fileName:
type: string
format: binary
Also, I've tried these two dependencies:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
My last solution is to allow sending up to 2-3 MultipartFile
, but I would really like to avoid this. How can I configure this?
Upvotes: 4
Views: 6894
Reputation: 669
You can't do this in Swagger 2.x. As per Swagger doc.
However, uploading an arbitrary number of files (an array of files) is not supported. There is an open feature request at https://github.com/OAI/OpenAPI-Specification/issues/254. For now, you can use a binary string array as a workaround for uploading an arbitrary number of files:
Upvotes: 1