如何让Swagger UI将FileUpload请求体显示为文件上传按钮
问题描述
我正在开发用于文件上传的Quarkus REST API,想通过Swagger UI实现快速反馈,但Swagger UI无法正确渲染文件输入——它总是显示一个大文本框,而不是预期的文件选择框(像Swagger文档里那样可以选择文件上传)。我已经按照《RESTEasy Reactive指南》配置了接口接收文件作为请求体,这是Bug还是需要额外添加元数据来指定正确的输入视图?
重现细节
使用Quarkus 2.14,按照Quarkus RESTEasy指南中的示例即可重现问题:
Quarkus扩展依赖
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-openapi</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-swagger-ui</artifactId> </dependency>
RESTEasy接口代码
package com.me.example; import javax.enterprise.context.RequestScoped; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; import org.jboss.resteasy.reactive.PartType; import org.jboss.resteasy.reactive.RestForm; import org.jboss.resteasy.reactive.multipart.FileUpload; @Path("/files") @RequestScoped public class ExampleResource { public static class Person { public String firstName; public String lastName; } @POST public void multipart(@RestForm String description, @RestForm("image") FileUpload file, @RestForm @PartType(MediaType.APPLICATION_JSON) Person person) { } }
生成的OpenAPI文档
--- openapi: 3.0.3 info: title: API version: 0.1.0-SNAPSHOT paths: /files: post: tags: - Example Resource requestBody: content: application/x-www-form-urlencoded: schema: type: object properties: description: type: string image: $ref: '#/components/schemas/FileUpload' person: $ref: '#/components/schemas/Person' encoding: person: contentType: application/json responses: "201": description: Created components: schemas: FileUpload: type: object Person: type: object properties: firstName: type: string lastName: type: string
问题原因与解决方案
问题根源
- 生成的OpenAPI文档中,请求体媒体类型被错误识别为
application/x-www-form-urlencoded,但文件上传需要使用multipart/form-data类型。 FileUpload被解析为普通object类型,未标记为文件类型,导致Swagger UI无法识别这是文件输入控件。
解决方案
需要通过两个关键修改让Swagger UI正确识别文件上传字段:
- 指定请求媒体类型:在
@POST注解上添加@Consumes(MediaType.MULTIPART_FORM_DATA),明确告知OpenAPI生成器这是多部分表单请求。 - 标记文件字段类型:使用
@Schema注解将FileUpload参数标记为二进制文件类型。
修改后的接口代码:
package com.me.example; import javax.enterprise.context.RequestScoped; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; import org.jboss.resteasy.reactive.PartType; import org.jboss.resteasy.reactive.RestForm; import org.jboss.resteasy.reactive.multipart.FileUpload; import org.eclipse.microprofile.openapi.annotations.media.Schema; @Path("/files") @RequestScoped public class ExampleResource { public static class Person { public String firstName; public String lastName; } @POST @Consumes(MediaType.MULTIPART_FORM_DATA) public void multipart(@RestForm String description, @RestForm("image") @Schema(type = "string", format = "binary") FileUpload file, @RestForm @PartType(MediaType.APPLICATION_JSON) Person person) { } }
验证效果
修改后重新生成的OpenAPI文档会将请求体媒体类型改为multipart/form-data,image字段会被标记为string(binary)类型,此时Swagger UI会自动渲染为文件选择框,而非文本框。
内容的提问来源于stack exchange,提问作者oaklandcorp-jkaiser
相关产品推荐
相关产品推荐

