Не удалось найти MessageBodyReader приложения типа контента /json и введите класс java.lang.String

Я использую клиент RestEasy с поставщиками Jackson и получаю вышеуказанную ошибку.

Клиентский код:

ClientRequest request = new ClientRequest(url);
request.accept(MediaType.APPLICATION_JSON);
ClientResponse<String> response = request.get(String.class);

if (response.getStatus() != 200) {
  throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}

BufferedReader br =
  new BufferedReader(new InputStreamReader(new ByteArrayInputStream(response.getEntity().getBytes())));

response.getEntity() генерирует исключение ClientResponseFailure с ошибкой

Unable to find a MessageBodyReader of content-type application/json and type class java.lang.String

Мой код на стороне сервера ниже:

@GET
@Path("/{itemId}")
@Produces(MediaType.APPLICATION_JSON)
public String item(@PathParam("itemId") String itemId) {
  //custom code

  return gson.toJSON(object);
}

Ответы

Ответ 1

Вы можете попытаться добавить следующую зависимость к вашему maven pom.

   <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson-provider</artifactId>
    <version>2.3.4.Final</version>
   </dependency>

Ответ 2

Проблема в том, что RestEasy не может найти поставщика Jackson. Мне пришлось вручную зарегистрировать его по следующему коду:

   ResteasyProviderFactory instance=ResteasyProviderFactory.getInstance();
    RegisterBuiltin.register(instance);
    instance.registerProvider(ResteasyJacksonProvider.class);

Все отлично работает с этим. Но я все еще недовольна решением, поскольку Resteasy должен сканировать провайдеры и регистрировать их автоматически.

Ответ 3

Просто добавив строку org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProvider в файл META-INF/services/javax.ws.rs.ext.Providers, решает проблему.

Этот файл включен в resteasy-jackson-providers.jar, но тот же файл также включен в другую банку, restasy-jaxrs.jar и для исполняемого файла jar, которые используют обе эти банки, они не объединены!

Ответ 4

Я не знаю полного обоснования этого, но мы столкнулись с одной и той же проблемой (несколько раз: P), и вам нужно изменить MediaType на TEXT_PLAIN.

Или вы также можете позволить JAX-RS выполнить задание для вас: вместо того, чтобы делать gson.toJSON(объект), просто возвращайте объект и меняйте свою подпись метода на любой класс. JAX-RS (RESTEasy в вашем случае) автоматически вызовет Jackson (если он правильно настроен) и сериализует ваш объект в json. Затем на стороне клиента вы запросите для этого же класса вместо String, и все должно работать самостоятельно. Я не особенно знаком с ClientRequest/Response, поэтому он может не работать, как я сказал; вместо этого мы используем функциональность прокси-сервера RESTEasy на стороне клиента (см. ProxyFactory). Тем не менее, JAX-RS/RESTEasy может автоматически сериализовать/десериализовать json на стороне клиента, поэтому определенно способ.

Ответ 5

Если вы действительно хотите, чтобы JAX-RS полностью выполнил сериализацию (вместо ручного вызова GSON), используйте StreamingOutput (т.е. оберните вывод как StreamingOutput, верните этот объект).

Ответ 6

У меня была аналогичная проблема, и я понял, что проблема связана с версией resteasy-jackson-provider. Я просто перешел от 3.0.4.Final до 3.0.5.Final, и проблема исчезла.

Кроме того, я также понял, что если я изменю третью строку на следующую, результат будет ожидаемым, без необходимости изменять зависимости.

Response response = request.get(Object.class).toString();