Чтение тела ответа в клиенте JAX-RS из почтового запроса
Имея какой-то прокси-сервер между мобильным приложением и веб-сервисом, мы с недоумением отзываем ответ при публикации почтового запроса. Мы получаем ответ со статусом 200: ОК. Но мы не можем найти/извлечь тело ответа JSON.
Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(WEBSERVICE_BASE_LOCATION + "mobileDevices?operatorCode=KPNSCP");
String jsonString = "{\"osVersion\":\"4.1\",\"apiLevel\":16,\"devicePlatform\":\"ANDROID\"}";
Builder builder = webTarget.request();
Response response = builder.post(Entity.json(jsonString));
Мы используем JAX-RS.
Может ли кто-нибудь указать некоторые подсказки для извлечения тела JSON (String
) из ответа сервера?
Ответы
Ответ 1
Попробуйте следующее:
String output = response.getEntity(String.class);
ИЗМЕНИТЬ
Благодаря @Martin Spamer, чтобы упомянуть, что он будет работать только для банок Джерси 1.x. Для Jersey 2.x используйте
String output = response.readEntity(String.class);
Ответ 2
Я только что нашел решение для jaxrs-ri-2.16 - просто используйте
String output = response.readEntity(String.class)
это доставляет содержимое, как ожидалось.
Ответ 3
В моем случае использования ни один из предыдущих ответов не работал, потому что я писал серверную сторону unit test, которая не срабатывала из-за следующего сообщения об ошибке, как описано в Не удалось выполнить Mock Вопрос о объекте "Ответ на вопрос о Джерси-клинике" :
java.lang.IllegalStateException: Method not supported on an outbound message.
at org.glassfish.jersey.message.internal.OutboundJaxrsResponse.readEntity(OutboundJaxrsResponse.java:145)
at ...
Это исключение произошло в следующей строке кода:
String actJsonBody = actResponse.readEntity(String.class);
Исправление заключалось в том, чтобы превратить проблемную строку кода в:
String actJsonBody = (String) actResponse.getEntity();
Ответ 4
У меня также была такая же проблема, пытаясь запустить код вызова unit test, который использует readEntity
. Нельзя использовать getEntity
в производственном коде, потому что это просто возвращает ByteInputStream
, а не содержимое тела, и я не добавляю производственный код, который попадает только в модульные тесты.
Мое решение состояло в том, чтобы создать ответ, а затем использовать шпиона Mockito для извлечения метода readEntity
:
Response error = Response.serverError().build();
Response mockResponse = spy(error);
doReturn("{jsonbody}").when(mockResponse).readEntity(String.class);
Обратите внимание, что вы не можете использовать параметр when(mockResponse.readEntity(String.class)
, потому что это вызывает тот же IllegalStateException
.
Надеюсь, это поможет!
Ответ 5
Согласно документации, метод getEntity в Jax rs 2.0 возвращает InputStream. Если вам нужно преобразовать в InputStream в String с форматом JSON, вам нужно привести два формата. Например, в моем случае я реализовал следующий метод:
private String processResponse(Response response) {
if (response.getEntity() != null) {
try {
InputStream salida = (InputStream) response.getEntity();
StringWriter writer = new StringWriter();
IOUtils.copy(salida, writer, "UTF-8");
return writer.toString();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
return null;
}
почему я реализовал этот метод. Поскольку читают в разных блогах, что многие разработчики имеют ту же проблему с версией в jaxrs, используя следующие методы
String output = response.readEntity(String.class)
а также
String output = response.getEntity(String.class)
Первый работает с использованием jersey-client из библиотеки com.sun.jersey, а второй - с использованием jersey-client из org.glassfish.jersey.core.
Это ошибка, которую мне представляли: org.glassfish.jersey.client.internal.HttpUrlConnector $ 2 не может быть приведен к java.lang.String.
Я использую следующую Maven зависимость:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>
Что я не знаю, так это то, почему метод readEntity не работает. Я надеюсь, что вы можете использовать решение.
Карлос Сепеда
Ответ 6
Понимая пересмотр кода, я нашел причину, почему метод чтения не работал для меня. Проблема заключалась в том, что одна из зависимостей, которые использовал в моем проекте трикотаж 1.x. Обновите версию, настройте клиент и все работает.
Я использую следующую Maven зависимость:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>
С уважением
Карлос Сепеда