Может ли веб-служба получить настраиваемое сообщение об ошибке от веб-службы на другом сервере?

У меня есть веб-служба, работающая на сервере A, которая возвращает настраиваемое сообщение об ошибке в объекте Java ResponseEntity, например:

return new ResponseEntity<String>("My custom error message.", HttpStatus.BAD_REQUEST);

У меня есть другая веб-служба, запущенная на сервере B, которая вызывает веб-службу на сервере A, но вместо «Моего настраиваемого сообщения об ошибке» я получаю следующее:

can't parse JSON. Raw result: Server returned HTTP response code: 400

Если я вызываю веб-службу на сервере A напрямую, я получаю сообщение об ошибке 400 с «Моим настраиваемым сообщением об ошибке», как и ожидалось.

Я изолировал проблему, когда сервер B пытается прочитать ответ от сервера A.

BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

Когда сервер B получает ошибку 400 от сервера A, conn.getInputStream () генерирует исключение IOException, которое перехватывается, но «Мое пользовательское сообщение об ошибке» теряется в исключении.

catch (IOException e) {
    return new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
}

Может ли сервер B вернуть настраиваемое сообщение об ошибке с сервера A? Как это сделать?

Я использую Java 8, Spring Boot 2.0.2, Tomcat 9 и Swagger UI 2.8 для тестирования веб-сервисов.

ОБНОВЛЕНИЕ: если сервер A возвращает код 200 вместо 400, то исключение IOException не создается на сервере B. Вместо этого создается исключение JsonParseException, а сервер B возвращает «Мое настраиваемое сообщение об ошибке».

Если сервер B ожидает JSON, попробуйте добавить кавычки к строковому значению.

chrylis -cautiouslyoptimistic- 25.08.2018 02:40

Это удаляет часть «не удается проанализировать JSON. Необработанный результат:», но клиент по-прежнему не знает, почему сервер вернулся с ошибкой HTTP 400.

MasterMirror 28.08.2018 00:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
195
1

Ответы 1

Я думаю, причина, по которой это происходит, заключается в том, что ваше исключение, хотя и правильно генерируется из A, обрабатывается внутри conn.getInputStream, который видит исключение BAD_REQUEST. Одно из возможных решений, которое я могу предположить, заключается в том, что вы каким-то образом проверяете, прежде чем делать объект чтения потока ввода, проверять погодное соединение, выдает какое-то исключение или нет.

try{
    conn.open();
    BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()));
    }catch(Exception e){
     return new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
}

Метод, похожий на conn.open, должен генерировать ваше собственное исключение перед созданием объекта считывателя входного потока.

Я мог бы попросить сервер B проверить содержимое тела, прежде чем он отправит запрос на сервер A, но сервер A уже проверяет содержимое, которое он получает. Я бы хотел избежать дублирования кода на обоих серверах, но это кажется неизбежным.

MasterMirror 28.08.2018 01:27

Другие вопросы по теме