如何在带有Quarkus的RestEasy中为MultipartFormDataInput提供醒目的注解

问题描述

在使用RestEasy框架处理Quarkus时,我具有使用MultipartFormDataInput上传文件功能。此功能按预期工作,但我无法为swagger UI提供适当的开放API注释。我尝试了多种选择和组合,但没有取得成果。请帮我。我在下面的示例代码中提供。

@Operation(summary = "Upload a single file",description = "Upload a single file")
    @APIResponses({
            @APIResponse(responseCode = "200",description = "Upload file successfully"),@APIResponse(name = "500",responseCode = "500",description = "Internal service error") })
    @RequestBody(content = @Content(
            mediaType = MediaType.MULTIPART_FORM_DATA,schema = @Schema(type = SchemaType.STRING,format = "binary"),encoding = @Encoding(name = "attachment",contentType = "application/octet-stream")))
    @POST
    @Path("/singleFile")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response handleFileUpload(@MultipartForm MultipartFormDataInput input) {
        String fileName = null;

        Map<String,List<InputPart>> uploadForm = input.getFormDataMap();
        // Get file data to save
        List<InputPart> inputParts = uploadForm.get("attachment");
        for (InputPart inputPart : inputParts) {
            try {
                MultivaluedMap<String,String> header = inputPart.getHeaders();
                fileName = getFileName(header);
                InputStream inputStream = inputPart.getBody(InputStream.class,null);
                byte[] bytes = IoUtils.toByteArray(inputStream);
                File customDir = new File(UPLOAD_DIR);
                if (!customDir.exists()) {
                    customDir.mkdir();
                }
                fileName = customDir.getCanonicalPath() + File.separator + fileName;
                Files.write(Paths.get(fileName),bytes,StandardOpenoption.CREATE);
                return Response.status(200).entity("Uploaded file name : " + fileName).build();
            } catch (Exception e) {
                e.printstacktrace();
            }
        }
        return Response.status(200).entity("Uploaded file name : " + fileName).build();
    }

我还参考了以下链接

https://community.smartbear.com/t5/Swagger-Open-Source-Tools/How-to-swagger-annotate-multipart-form-data-with-resteasy/td-p/178776

https://github.com/swagger-api/swagger-core/issues/3050

如果我创建一个带有MultipartBody批注的名为@Schema(type = SchemaType.STRING,format = "binary") and @PartType(MediaType.APPLICATION_OCTET_STREAM)的单独类,则能够生成swagger UI。但是我的要求是仅使用MultipartFormDataInput

解决方法

您几乎在那里:)只需在RequestBody / Schema中使用专用的类,并告诉OpenAPI忽略方法的参数即可。

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@RequestBody(content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA,schema = @Schema(implementation = MultipartBody.class))
)
@Operation(operationId = "uploadFile")
public Response uploadFile(@Parameter(hidden = true) MultipartFormDataInput input) {
//... your logic here
}

需要注意的两件事:@Parameter(hidden = true)告诉Smallrye OpenAPI在生成模式模型时不要考虑您的MultipartFormDataInput。然后,您需要使用@RequestBody明确地描述模式,其中MultipartBody是一个描述所有输入参数的类(您可以在其中添加更多参数,例如,要与其他参数一起传递文件有效载荷)

public class MultipartBody {

    @FormParam("file")
    @Schema(type = SchemaType.STRING,format = "binary",description = "file data")
    public String file;


    @FormParam("fileName")
    @PartType(MediaType.TEXT_PLAIN)
    public String fileName;
}

只需确保@FormParam中带有MultipartBody的带注释的字段与您希望在MultipartFormDataInput中找到的。,parts匹配-例如,在您的情况下,文件属性应具有@FormParam("attachment")