Зчитати тіло відповіді в клієнті JAX-RS із запиту на повідомлення


75

Маючи якийсь проксі-сервер між мобільним додатком та веб-службою, ми здивовані реакцією, коли надсилаємо запит на публікацію. Ми отримуємо відповідь із статусом 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) із відповіді сервера?


4
Нам довелося змінити його на: String output = response.readEntity(String.class);Щоб це працювало. Дуже дякую!
user2657714

Відповіді:


169

Спробуйте це:

String output = response.getEntity(String.class);

РЕДАГУВАТИ

Дякую @Martin Spamer, щоб сказати, що він буде працювати лише для банок Jersey 1.x. Для Джерсі 2.x використання

String output = response.readEntity(String.class);

46
Це буде працювати лише з Jax 1.x, з Джерсі: 2.x і далі, яку використовує OP (ми можемо визначити з його використання ClientBuilder.newClient ();). Відповідьresponse.readEntity(String.class);
Мартін Спамер

3
Це не працює для jaxrs-ri-2.16, тут ви отримаєте org.glassfish.jersey.client.HttpUrlConnector$2@1255b1d1як вихід.
col.panic

дякую, я застряг у цьому надовго, оскільки використовував getEntity () для читання тексту повідомлення відповіді. getEntity () працює лише з Jersey 1.x, а Jersey 2.0 має підтримку response.readEntity (), щоб отримати тіло повідомлення відповіді.
spectre007

Зверніть увагу, що якщо ви отримаєте com.owlike.genson.stream.JsonStreamException: Readen value can not be converted to String, вам потрібно буде прочитати потік відповідей вручну, щоб отримати рядок JSON. Це сталося для мене з Джерсі 1.19.
dvlcube 03.03.20

17

Я щойно знайшов рішення для jaxrs-ri-2.16 - просто використовуйте

String output = response.readEntity(String.class)

це забезпечує вміст, як очікувалося.


14
Розробники Джерсі збивають мене з розуму. Імена всіх методів версій та / або весь робочий процес різко змінюються. Це все одно, що грати в гру Майнер. Знайдіть усі міни з нуля.
Альфіше

2
Вам не подобається спритність? :)
Примхливий

8
@Whimusical Я думаю, що йому подобається зворотна сумісність :)
Христо Врігазов,

13

Для мого випадку жодна з попередніх відповідей не спрацювала, оскільки я писав серверний модульний тест, який провалився через таке повідомлення про помилку, як описано в запитанні про об'єкт відповіді клієнта Джерсі з Glassfish :

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();

3
getEntity не буде автоматично читати будь-який резервний InputStream, тому будьте обережні.
Бен,

4

У мене також була та сама проблема, намагаючись запустити модульний тестовий код виклику, який використовує readEntity. Не можна використовувати getEntityу виробничому коді, оскільки це просто повертає a, 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.

Сподіваюся, це допомагає!


1
Дякую! Ви, мабуть, перша людина, яка насправді зрозуміла питання ОП. Для всіх вас, хто реагує першими, ніхто не цікавиться, наскільки ви розумні. Вони хочуть виправити свою проблему. Їх не цікавить, чому джерсі не дозволяє вам викликати readResponse в юніт-тесті.
Джон Калькот,

0

Відповідно до документації, метод 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-клієнта з бібліотеки com.sun.jersey, а другий - за допомогою клієнта jersey з 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 не працює. Сподіваюся, ви можете використовувати рішення.

Карлос Чепеда


0

Розуміючи перегляд коду, я знайшов причину, чому метод читання у мене не спрацював. Проблема полягала в тому, що одна із залежностей, яку мій проект використовував jersey 1.x. Оновіть версію, налаштуйте клієнта і все працює.

Я використовую таку залежність maven:

<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.28</version>

З повагою

Карлос Чепеда

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.