#java #spring-boot #exception #controller #resttemplate
#java #spring-boot #исключение #контроллер #resttemplate
Вопрос:
В моем контроллере есть 2 (A и B) REST API. A может вызвать B с помощью RestTemplate. Оба A и B генерируют исключение, теперь A получил запрос, затем вызов B и B генерируют исключение, но я получаю только код состояния 500, никаких сведений об исключении не возвращено.
@Autowired
private RestTemplate internalRestRouter;
@PostMapping("/A")
public Object handleACommand(@RequestBody Map<String, Object> payload) throws CliException {
return internalRestRouter.postForObject("http://localhost:8080/B", null, Object.class);
}
@PostMapping("/B")
public Object handleBCommand() throws CliException {
throw new CliException("B Exception details");
}
Как я могу получить сведения об исключении, выдаваемом B при вызове A?
Комментарии:
1. добавил ли ‘B’ сведения об исключении в тело своего ответа (HttpResponse.setEntity(…)) ? пытался ли ‘A’ извлечь объект из ответа B?
2. @ruhul В моем коде нет явной оболочки тела ответа. Возвращайте результат json только в том случае, если все в порядке, или генерируйте исключение.
Ответ №1:
Используйте ControllerAdvice для обработки обоих исключений.
Комментарии:
1. Не могли бы вы, пожалуйста, добавить больше деталей / кода для уточнения вашего ответа.
Ответ №2:
предложение @Wd Ly я поддержал
Написание рекомендаций для контроллера Разработчики протестировали множество способов заставить класс рекомендаций для контроллера работать. После напряженной работы они нашли следующие моменты, которые следует учитывать:
Создайте свои собственные классы исключений. Несмотря на то, что Spring предоставляет множество классов, представляющих распространенные исключения в приложении, лучше написать свой собственный или расширить существующие. Один класс рекомендаций контроллера для каждого приложения. Было бы неплохо поместить все обработчики исключений в один класс вместо того, чтобы комментировать несколько них с помощью @ControllerAdvice. Напишите метод HandleException. Это исключение должно быть помечено с помощью @ExceptionHandler и будет обрабатывать все исключения, объявленные в нем, а затем будет делегировано определенному методу обработчика. Добавьте один обработчик метода для каждого исключения. Представьте, что вы хотите обработать исключение UserNotFoundException, затем создайте handleUserNotFoundException. Создайте метод, который отправляет ответ пользователю. Методы обработчика предназначены для выполнения логики обработки данного исключения, затем они будут вызывать метод, который отправляет ответ. Этот метод получит список ошибок в виде тела и конкретного статуса HTTP.
@ControllerAdvice
public class GlobalExceptionHandler {
/** Provides handling for exceptions throughout this service. */
@ExceptionHandler({ UserNotFoundException.class, ContentNotAllowedException.class })
public final ResponseEntity<ApiError> handleException(Exception ex, WebRequest request) {
HttpHeaders headers = new HttpHeaders();
if (ex instanceof UserNotFoundException) {
HttpStatus status = HttpStatus.NOT_FOUND;
UserNotFoundException unfe = (UserNotFoundException) ex;
return handleUserNotFoundException(unfe, headers, status, request);
} else if (ex instanceof ContentNotAllowedException) {
HttpStatus status = HttpStatus.BAD_REQUEST;
ContentNotAllowedException cnae = (ContentNotAllowedException) ex;
return handleContentNotAllowedException(cnae, headers, status, request);
} else {
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
return handleExceptionInternal(ex, null, headers, status, request);
}
}
/** Customize the response for UserNotFoundException. */
protected ResponseEntity<ApiError> handleUserNotFoundException(UserNotFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
List<String> errors = Collections.singletonList(ex.getMessage());
return handleExceptionInternal(ex, new ApiError(errors), headers, status, request);
}
/** Customize the response for ContentNotAllowedException. */
protected ResponseEntity<ApiError> handleContentNotAllowedException(ContentNotAllowedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
List<String> errorMessages = ex.getErrors()
.stream()
.map(contentError -> contentError.getObjectName() " " contentError.getDefaultMessage())
.collect(Collectors.toList());
return handleExceptionInternal(ex, new ApiError(errorMessages), headers, status, request);
}
/** A single place to customize the response body of all Exception types. */
protected ResponseEntity<ApiError> handleExceptionInternal(Exception ex, ApiError body, HttpHeaders headers, HttpStatus status, WebRequest request) {
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
request.setAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE, ex, WebRequest.SCOPE_REQUEST);
}
return new ResponseEntity<>(body, headers, status);
}
}