如何在Spring Doc的Swagger-UI中添加支持Flux<ByteBuffer>的文件上传按钮
Spring Doc 1.6.12 实现Swagger UI文件上传按钮(保留Flux入参)
问题背景
我使用Spring Doc 1.6.12,依赖配置如下:
<spring-doc.version>1.6.12</spring-doc.version> ... <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webmvc-core</artifactId> <version>${spring-doc.version}</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-webflux-ui</artifactId> <version>${spring-doc.version}</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-data-rest</artifactId> <version>${spring-doc.version}</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-security</artifactId> <version>${spring-doc.version}</version> </dependency>
控制器上传方法定义如下:
@PostMapping(produces = "application/hal+json") @ResponseStatus(code = HttpStatus.CREATED) public Mono<ResponseEntity<MyDTO>> upload( @RequestBody Flux<ByteBuffer> data, @RequestHeader(name = CONTENT_LENGTH) long contentLength, @RequestHeader(name = CONTENT_TYPE, required = false) MediaType contentType, @RequestHeader(name = CONTENT_DISPOSITION) @ContentDispositionConstraint ContentDisposition contentDisposition, @RequestParam(name = "archive", required = false, defaultValue = "false") boolean archive, @RequestParam(name = "folder", required = false) @Pattern(regexp = FOLDER_PATTERN) String folder, @RequestParam(name = "folderOwner", required = false) String folderOwner, @RequestParam(value = "folderUuid", required = false) UUID folderUuid, @RequestParam(name = "expirationDate", required = false) Instant expirationDate, JwtAuthenticationToken jwtToken, ServerHttpRequest request) { // 业务逻辑 }
当前Swagger UI中无法显示文件上传按钮,若将@RequestBody Flux<ByteBuffer> data改为@RequestPart ("file") MultipartFile data可显示按钮,但底层代码依赖Flux<ByteBuffer>,因此希望保留原有入参实现文件上传按钮的显示。
解决方案
方案1:通过OpenAPI注解手动声明文件上传类型
在Flux<ByteBuffer>参数上添加Swagger专属的@RequestBody注解(注意是io.swagger.v3.oas.annotations.parameters.RequestBody,而非Spring原生注解),同时修改@PostMapping的consumes属性指定请求媒体类型为multipart/form-data:
@PostMapping(produces = "application/hal+json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @ResponseStatus(code = HttpStatus.CREATED) public Mono<ResponseEntity<MyDTO>> upload( @io.swagger.v3.oas.annotations.parameters.RequestBody( content = @Content( mediaType = MediaType.MULTIPART_FORM_DATA_VALUE, schema = @Schema(type = "string", format = "binary") ), required = true ) @RequestBody Flux<ByteBuffer> data, // 其他参数保持不变 ) { // 业务逻辑 }
方案2:自定义OperationCustomizer修改接口文档定义
如果注解方式不生效,可以通过自定义OperationCustomizer手动修改该接口的请求体配置:
@Configuration public class SpringDocCustomConfig { @Bean public OperationCustomizer fileUploadOperationCustomizer() { return (operation, handlerMethod) -> { // 匹配目标上传方法 if ("upload".equals(handlerMethod.getMethod().getName())) { // 构建文件上传的Content定义 Content multipartContent = new Content() .addMediaType(MediaType.MULTIPART_FORM_DATA_VALUE, new MediaType().schema(new Schema().type("string").format("binary"))); // 替换接口的RequestBody配置 operation.requestBody(new RequestBody().content(multipartContent).required(true)); } return operation; }; } }
同时需要确保@PostMapping添加consumes = MediaType.MULTIPART_FORM_DATA_VALUE属性。
注意事项
- 必须指定
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,否则Swagger UI无法识别该请求为文件上传类型 - Spring WebFlux会自动将
multipart/form-data类型的请求体转换为Flux<ByteBuffer>,无需额外编写转换逻辑 - 测试时,Swagger UI会显示文件上传按钮,上传文件后,请求会被正确映射到原有方法的
Flux<ByteBuffer>参数
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

