简体   繁体   English

使用 Jersey 客户端发送多部分/混合请求

[英]Sending multipart/mixed request with Jersey Client

I want to dialogue with this API service programmatically using Jersey ( https://eclipse-ee4j.github.io/jersey/ ) I want to dialogue with this API service programmatically using Jersey ( https://eclipse-ee4j.github.io/jersey/ )

here's the Rest Controller implementation in Spring:这是 Spring 中的 Rest Controller 实现:

@PostMapping(
      value = "/api/my-endpoint",
      consumes = MediaType.MULTIPART_MIXED_VALUE)
  public void enrichInvoice(@RequestPart("metadata") Map<String, Object> request,
      @RequestPart("human") MultipartFile humanFile) {
    log.info(String.format("received request:%n%s", request));
  }

my client implementation would be like this我的客户实现是这样的

...
     final Client client = ClientBuilder.newClient(new ClientConfig()
          .register(MultiPartFeature.class)
          .register(JacksonFeature.class)
      );

      final FileDataBodyPart filePart = new FileDataBodyPart("human",myFile()));

      final BodyPart metadata = new BodyPart().entity(voBuilder.generateMetadata());

      final MultiPart multiPartEntity = new MultiPart();
      multiPartEntity.bodyPart(metadata, MediaType.APPLICATION_JSON_TYPE);
      multiPartEntity.bodyPart(filePart);

      final WebTarget target = client
          .target("http://localhost:8080/api/my-endpoint");
      final Entity<MultiPart> entity = Entity
          .entity(multiPartEntity, multiPartEntity.getMediaType());
      log.info(entity.toString());
      final Response response = target
          .request()
          .post(entity);
      log.info(String.format("%s", response.readEntity(String.class)));
      response.close();
...

But i keep getting this error:但我不断收到此错误:

Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'metadata' is not present]

which is because the metadata part has to be named "metadata".这是因为元数据部分必须命名为“元数据”。 and I cannot find a way to name it using BodyPart.而且我找不到使用 BodyPart 命名它的方法。 I also tried using FormDataBodyPart to build the metadata我还尝试使用 FormDataBodyPart 构建元数据

FormDataBodyPart metadataBodyPart = new FormDataBodyPart("metadata", metadata,
          MediaType.APPLICATION_JSON_TYPE);

but with the same result.但结果相同。

Can you help me figure out what am I missing in the bodyPart definition?你能帮我弄清楚我在 bodyPart 定义中遗漏了什么吗?

Thanks谢谢


EDIT: here's the http request sent from my client implementation编辑:这是从我的客户端实现发送的 http 请求

Content-Type: multipart/mixed;boundary=Boundary_1_1972899462_1597045386454
User-Agent: Jersey/2.29 (HttpUrlConnection 11.0.8)
MIME-Version: 1.0
Host: localhost:8080
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 765

--Boundary_1_1972899462_1597045386454
Content-Type: application/json

{"value":"key"}
--Boundary_1_1972899462_1597045386454
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="file.zip"; modification-date="Wed, 05 Aug 2020 16:52:52 GMT"; size=0; name="human"


--Boundary_1_1972899462_1597045386454--
]

The solution, even if not optimal, was to treat the metadata as a text file解决方案,即使不是最佳的,也是将元数据视为文本文件

final Path tempFile = Files.createTempFile("prefix", "suffix");
File fileMetadata = Files.write(tempFile.toAbsolutePath(), JsonUtils.toString(metadata).getBytes());

final FileDataBodyPart metadataBodyPart = new FileDataBodyPart(
          "metadata",
          fileMetadata,
          MediaType.APPLICATION_JSON_TYPE);

final FileDataBodyPart human = new FileDataBodyPart("human", new File(humanReadableFile.getFileKey()));

try (final MultiPart multiPartEntity = new MultiPart()) {
        multiPartEntity.bodyPart(metadataBodyPart);
        multiPartEntity.bodyPart(human);

    final Response response = client
        .target("http://localhost:8080/api/my-endpoint")
        .request()
        .post(Entity.entity(multiPartEntity, multiPartEntity.getMediaType()));
    log.debug(String.valueOf(response.getStatus()));
    log.debug(response.readEntity(String.class));
}

In this way the request body has to parts named "metadata" and "human" as requested by the controller implementation and still maintain the multipart/mixed content-type.通过这种方式,请求正文必须按照 controller 实现的要求,包含名为“元数据”和“人类”的部分,并且仍然保持多部分/混合内容类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM