如何在使用Quarkus的RestEasy中为MultipartFormDataInput提供Swagger注解

huangapple go评论104阅读模式
英文:

How to provide swagger annotation for MultipartFormDataInput in RestEasy with Quarkus

问题

在使用 Quarkus 和 RestEasy 框架工作时,我有一个使用 MultipartFormDataInput 上传文件的功能。这个功能按预期工作,但我无法为 Swagger UI 提供正确的 Open API 注解。我尝试了多个选项和组合,但没有成功。请帮助我。我提供以下示例代码。

  1. @Operation(summary = "上传单个文件", description = "上传单个文件")
  2. @APIResponses({
  3. @APIResponse(responseCode = "200", description = "成功上传文件"),
  4. @APIResponse(name = "500", responseCode = "500", description = "内部服务错误")
  5. })
  6. @RequestBody(content = @Content(
  7. mediaType = MediaType.MULTIPART_FORM_DATA,
  8. schema = @Schema(type = SchemaType.STRING, format = "binary"),
  9. encoding = @Encoding(name = "attachment", contentType = "application/octet-stream")))
  10. @POST
  11. @Path("/singleFile")
  12. @Consumes(MediaType.MULTIPART_FORM_DATA)
  13. @Produces(MediaType.TEXT_PLAIN)
  14. public Response handleFileUpload(@MultipartForm MultipartFormDataInput input) {
  15. String fileName = null;
  16. Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
  17. // 获取要保存的文件数据
  18. List<InputPart> inputParts = uploadForm.get("attachment");
  19. for (InputPart inputPart : inputParts) {
  20. try {
  21. MultivaluedMap<String, String> header = inputPart.getHeaders();
  22. fileName = getFileName(header);
  23. InputStream inputStream = inputPart.getBody(InputStream.class, null);
  24. byte[] bytes = IOUtils.toByteArray(inputStream);
  25. File customDir = new File(UPLOAD_DIR);
  26. if (!customDir.exists()) {
  27. customDir.mkdir();
  28. }
  29. fileName = customDir.getCanonicalPath() + File.separator + fileName;
  30. Files.write(Paths.get(fileName), bytes, StandardOpenOption.CREATE);
  31. return Response.status(200).entity("已上传文件名 : " + fileName).build();
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. return Response.status(200).entity("已上传文件名 : " + fileName).build();
  37. }

我还参考了以下链接:

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")@PartType(MediaType.APPLICATION_OCTET_STREAM) 注解,我可以生成 Swagger UI。但我的要求是仅使用 MultipartFormDataInput

英文:

while working on Quarkus with the RestEasy framework, I have the functionality to upload a file using MultipartFormDataInput. This functionality is working as expected, but I am unable to provide proper open API annotation for swagger UI. I have tried multiple options and combinations, but it did not bear fruit. Please help me. I provide below the sample code.

  1. @Operation(summary = &quot;Upload a single file&quot;, description = &quot;Upload a single file&quot;)
  2. @APIResponses({
  3. @APIResponse(responseCode = &quot;200&quot;, description = &quot;Upload file successfully&quot;),
  4. @APIResponse(name = &quot;500&quot;, responseCode = &quot;500&quot;, description = &quot;Internal service error&quot;) })
  5. @RequestBody(content = @Content(
  6. mediaType = MediaType.MULTIPART_FORM_DATA,
  7. schema = @Schema(type = SchemaType.STRING, format = &quot;binary&quot;),
  8. encoding = @Encoding(name = &quot;attachment&quot;, contentType = &quot;application/octet-stream&quot;)))
  9. @POST
  10. @Path(&quot;/singleFile&quot;)
  11. @Consumes(MediaType.MULTIPART_FORM_DATA)
  12. @Produces(MediaType.TEXT_PLAIN)
  13. public Response handleFileUpload(@MultipartForm MultipartFormDataInput input) {
  14. String fileName = null;
  15. Map&lt;String, List&lt;InputPart&gt;&gt; uploadForm = input.getFormDataMap();
  16. // Get file data to save
  17. List&lt;InputPart&gt; inputParts = uploadForm.get(&quot;attachment&quot;);
  18. for (InputPart inputPart : inputParts) {
  19. try {
  20. MultivaluedMap&lt;String, String&gt; header = inputPart.getHeaders();
  21. fileName = getFileName(header);
  22. InputStream inputStream = inputPart.getBody(InputStream.class, null);
  23. byte[] bytes = IOUtils.toByteArray(inputStream);
  24. File customDir = new File(UPLOAD_DIR);
  25. if (!customDir.exists()) {
  26. customDir.mkdir();
  27. }
  28. fileName = customDir.getCanonicalPath() + File.separator + fileName;
  29. Files.write(Paths.get(fileName), bytes, StandardOpenOption.CREATE);
  30. return Response.status(200).entity(&quot;Uploaded file name : &quot; + fileName).build();
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. return Response.status(200).entity(&quot;Uploaded file name : &quot; + fileName).build();
  36. }

I have also referred to the following links.

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

I am able to generate swagger UI if I create a separate class called MultipartBody with @Schema(type = SchemaType.STRING, format = &quot;binary&quot;) and @PartType(MediaType.APPLICATION_OCTET_STREAM) annotation. But my requirement is to use only MultipartFormDataInput.

答案1

得分: 5

你差不多就快成功了 如何在使用Quarkus的RestEasy中为MultipartFormDataInput提供Swagger注解 只需要在你的RequestBody/Schema中使用一个专门的类,并告诉OpenAPI忽略方法中的参数。

  1. @POST
  2. @Consumes(MediaType.MULTIPART_FORM_DATA)
  3. @RequestBody(content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA,
  4. schema = @Schema(implementation = MultipartBody.class))
  5. )
  6. @Operation(operationId = "uploadFile")
  7. public Response uploadFile(@Parameter(hidden = true) MultipartFormDataInput input) {
  8. //... 这里是你的逻辑
  9. }

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

  1. public class MultipartBody {
  2. @FormParam("file")
  3. @Schema(type = SchemaType.STRING, format = "binary", description = "文件数据")
  4. public String file;
  5. @FormParam("fileName")
  6. @PartType(MediaType.TEXT_PLAIN)
  7. public String fileName;
  8. }

请确保MultipartBody@FormParam注解的字段与你期望在MultipartFormDataInput中找到的“parts”匹配 - 例如,在你的情况下,文件属性应该有@FormParam("attachment")

英文:

You were almost there 如何在使用Quarkus的RestEasy中为MultipartFormDataInput提供Swagger注解 Just use a dedicated class in your RequestBody/Schema and tell OpenAPI ignore the params of your method.

  1. @POST
  2. @Consumes(MediaType.MULTIPART_FORM_DATA)
  3. @RequestBody(content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA,
  4. schema = @Schema(implementation = MultipartBody.class))
  5. )
  6. @Operation(operationId = &quot;uploadFile&quot;)
  7. public Response uploadFile(@Parameter(hidden = true) MultipartFormDataInput input) {
  8. //... your logic here
  9. }

Two things to note: @Parameter(hidden = true) tells Smallrye OpenAPI to not consider your MultipartFormDataInput when generating Schema model. Then you need to tell describe the schema explicitly, using @RequestBody, where MultipartBody is a class that describes all your input params(you can add more params there if you want to for example pass other props along with the file payload)

  1. public class MultipartBody {
  2. @FormParam(&quot;file&quot;)
  3. @Schema(type = SchemaType.STRING, format = &quot;binary&quot;, description = &quot;file data&quot;)
  4. public String file;
  5. @FormParam(&quot;fileName&quot;)
  6. @PartType(MediaType.TEXT_PLAIN)
  7. public String fileName;
  8. }

Just make sure that the @FormParam annotated fields in the MultipartBody match the ,,parts" that you expect to find in your MultipartFormDataInput - e.g. in your case the file attribute should have @FormParam(&quot;attachment&quot;)

huangapple
  • 本文由 发表于 2020年9月27日 00:10:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64079847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定