使用Quarkus处理multipart/form-data

4

我面临一个问题,就是无法在我的资源中获取表单,变量总是为空。

我的资源:

    @POST
    @Path("/upload-logo")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public String uploadLogo (@MultipartForm LogoMultipartForm logoMultipartForm) throws IOException {
        return this.companyService.uploadLogo(username, logoMultipartForm.logo);

    }

表单模型
public class LogoMultipartForm {

    @FormParam("logo")
    public byte[] logo;

    @FormParam("filename")
    @PartType("text/plain")
    public String fileName;
}

我的 Fetch 请求:

  uploadLogo: async (file: File) => {
    const form = new FormData();
    form.append("logo", file, "logo.png");
    form.append("filename", "test");

    const { query, abort } = HttpClient.POST(`${COMPANY_URL}/upload-logo`, form);
    let promise = query
      .then((res: any) => {
        console.log("Response", res);
        if (res.status === 200) {
          return res.text();
        } else {
          throw res;
        }
      })
      .then((url: any) => url);

    promise.cancel = abort;

    return promise;
  },

我的 HttpClient:

  POST: function (url: string, body: any, config?: any) {
    const controller = new AbortController();
    const signal = controller.signal;
    return { query: fetch(url, { signal, method: "POST", body, ...config }) as any, abort: () => controller.abort() };
  },

确保我正在使用代理进行测试,请求实际上是良好的:变量fileName和logo始终为null。
这是我的pom.xml文件:
  <dependencies>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-graphql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-flyway</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-jdbc-postgresql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-hibernate-orm-panache</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-reactive-pg-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-qute</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-oidc</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-multipart</artifactId>
    </dependency>

  </dependencies>

我不知道问题出在哪里。

我已经查看了resteasy官方的Multipart文档,但是没有发现问题。我已经测试了MultipartFormDataInput,但所有部分都是空的。

提前感谢您的帮助!:)

2个回答

2
您缺少依赖项:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-multipart-provider</artifactId>
</dependency>

请确保你的@PartType("text/plain")继承自org.jboss.resteasy包!以及@MultipartForm(import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;)
有一个很好的例子展示了它的工作原理:Quarkus教程。看看这些包!

Quarkus提供了一个名为quarkus-reasteasy-multipart的扩展,那么它与其他扩展有什么不同呢? - Dorian Maliszewski
quarkus-reasteasy-multipart 将默认字符集编码设置为 UTF-8,将默认媒体类型设置为 text/plain,并且它在传递依赖于 resteasy-multipart-provider - Hantsy

0

花了数小时来解决如何将多部分数据发送给客户端之间的问题

希望这个例子能帮到您

RestClient

@RegisterRestClient(configKey = "ted-api")
@RegisterClientHeaders(ClientHeaderFactory.class)
@RegisterProvider(value = ExceptionMapper.class)
@ApplicationScoped
public interface TedClient {
  
  @POST
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  @Path("/notices/submit")
  Response sendData(@MultipartForm TedBody data);
}

正文

@Getter
@Setter
@NoArgsConstructor
public class TedBody {
  @FormParam("notice")
  @PartFilename("notice-filename.xml") //partFileName is necessary for multipart mainly many developers missing it
  @PartType(MediaType.TEXT_XML)
  private byte[] notice;

  @FormParam("metadata")
  @PartType(MediaType.APPLICATION_JSON)
  private AuthorData AuthorData;

  public TedBody(byte[] notice) {
    this.notice = notice;
    this.authorData = new Author();
  }

如果您的系统需要检索多部分文件,则示例可能更容易 Rest

  @POST
  @Path("/upload")
  @Consumes(MULTIPART_FORM_DATA)
  @Produces(APPLICATION_JSON)
  public Response saveMultipartNoticeContainer(
      @MultipartForm @Valid RequestDto requestDto) {
    Resnponse noticeDto = noticeService.save(requestDto);
    return Response.accepted().entity(noticeDto).build();
  }

import org.jboss.resteasy.annotations.providers.multipart.PartType;

@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class NoticeRequestDto {

  @FormParam("notice")
  @PartType(MediaType.APPLICATION_OCTET_STREAM)
  private InputStream data;
}

对我们而言,Quarkus - 2.15.3.Final 是可用的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接