Как устранить исключение, возникающее при обработке вложенного MultipartInput с клиентским API RESTEasy? - PullRequest
0 голосов
/ 07 ноября 2019

Я построил следующий ресурс JAX-RS, который производит желаемый объект ответа, который является multipart / mixed с вложенным multipart / related с (на данный момент только один единственный) вложенным application / json .

@GET
@Path("test")
@Produces("multipart/mixed")
public Response test() {
  List<Entity> entities;
  ...
  final MultipartOutput multipartOutput = new MultipartOutput();
  entities.stream().map(entity -> {
    MultipartRelatedOutput multipartRelatedOutput = new MultipartRelatedOutput();
    multipartRelatedOutput.addPart(entity, MediaType.APPLICATION_JSON_TYPE);
    return multipartRelatedOutput;
  }).forEach(multipartRelatedOutput -> 
    multipartOutput.addPart(multipartRelatedOutput, MediaType.valueOf("multipart/related"))
  );
  return Response.ok(multipartOutput, MediaType.valueOf("multipart/mixed")).build();
}

Этот ресурс используется клиентом, построенным с помощью клиентского API RESTEasy через RESTEasy proxy framework . Сущность Response читается как MultipartInput . Тело каждой части теперь должно читаться как MultipartRelatedInput . Поскольку это невозможно (, вы можете проголосовать за ) , поскольку обходной путь для каждой части читается как MultipartInput .

public void get()
{
  try (Response response = this.proxy.test();) {
    ...
    MultipartInput multipartInput = response.readEntity(MultipartInput.class);
    for (InputPart inputPart : multipartInput.getParts()) {
    try {
      //MultipartRelatedInput relatedInput = inputPart.getBody(MultipartRelatedInput.class, null); // not working with NPE
      MultipartInput relatedInput = inputPart.getBody(MultipartInput.class, null);
      String json = relatedInput.getParts().get(0).getBodyAsString(); // fails
      // Entity entity = relatedInput.getParts().get(0).getBody(Entity.class, null); // also fails
    } catch (IOException exception) {}
  }
}

Считывание инкапсулированной сущности как JSON-String (для простоты, но также и чтение ее как объекта с типом класса сущности) завершается неудачей со следующим исключением:

Caused by: org.jboss.resteasy.spi.LoggableFailure: RESTEASY003880: Unable to find contextual data of type: javax.ws.rs.ext.Providers
    at org.jboss.resteasy.resteasy-jaxrs@3.7.0.Final//org.jboss.resteasy.core.ContextParameterInjector$GenericDelegatingProxy.invoke(ContextParameterInjector.java:77)
    at javax.ws.rs.api@1.0.2.Final//com.sun.proxy.$Proxy145.getMessageBodyReader(Unknown Source)
    at org.jboss.resteasy.resteasy-multipart-provider@3.7.0.Final//org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl$PartImpl.getBody(MultipartInputImpl.java:336)
    at org.jboss.resteasy.resteasy-multipart-provider@3.7.0.Final//org.jboss.resteasy.plugins.providers.multipart.MultipartInputImpl$PartImpl.getBodyAsString(MultipartInputImpl.java:392)

Похоже, что ResteasyProviderFactory contextualData пусто, когда ContextParameterInjector $ GenericDelegatingProxy.invoke вызывается.

Как решить эту проблему? Это ошибка?

Интересно, если я сделаю сам клиентский метод JAX-RS ресурсом и запрошу его у другого клиента, все будет работать. contextualData хорошо заполнен.

@GET
@Path("get")
@Produces(MediaType.APPLICATION_JSON)
public void get()
{
  try (Response response = this.proxy.test();) {
    ...
    MultipartInput multipartInput = response.readEntity(MultipartInput.class);
    for (InputPart inputPart : multipartInput.getParts()) {
    try {
      MultipartRelatedInput relatedInput = inputPart.getBody(MultipartRelatedInput.class, null);
    } catch (IOException exception) {}
  }
}

Но все же та же проблема, если метод клиента вызывается напрямую.

Среда - Windows 10 Pro 1903, OpenJDK11U-jdk_x64_windows_hotspot_11.0.4_11, WildFly 17.0.1.Final, RESTEasy 3.7.0.Final.

...