У меня есть веб-служба, работающая на сервере 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 возвращает «Мое настраиваемое сообщение об ошибке».
Это удаляет часть «не удается проанализировать JSON. Необработанный результат:», но клиент по-прежнему не знает, почему сервер вернулся с ошибкой HTTP 400.




Я думаю, причина, по которой это происходит, заключается в том, что ваше исключение, хотя и правильно генерируется из 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 уже проверяет содержимое, которое он получает. Я бы хотел избежать дублирования кода на обоих серверах, но это кажется неизбежным.
Если сервер B ожидает JSON, попробуйте добавить кавычки к строковому значению.