Добавление глобальной обработки ошибок для контроллеров Spring Rest

У меня много таких контроллеров

@RestController
@RequestMapping("/contracts")
public class ContractsController {

    @Autowired
    ContractsService service;

    @PostMapping("/selectAll")
    public WebMessageModel selectAll(@RequestBody ContractFiltersInputModel inputModel) {
        return new WebMessageModel(true, service.selectAll(inputModel));
    }
}

И у меня есть другой контроллер

@Controller
public class BaseController {

    private static Logger logger = LoggerFactory.getLogger(IndexController.class);

    @RequestMapping
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {

            String requestURI = request.getRequestURI();
            StringBuffer requestURL = request.getRequestURL();
            logger.info("-----requestURI => " + requestURI + ", requestURL => " + requestURL);

            request.getRequestDispatcher(requestURI).forward(request, response);

            logger.info("-----response has been commited");

        } catch (Throwable t) {
            t.printStackTrace();
            request.getRequestDispatcher("/handleException").forward(request, response);

        }

    }
}

Мне нужно, чтобы все входящие запросы проходили через этот BaseController, чтобы создать один глобальный блок TRY-CATCH. Как я могу это реализовать? Это действительно хорошая идея? Может есть еще какие-то офигенные подходы?

Если вы хотите иметь дело с исключениями, подумайте об использовании @ControllerAdvice

benjamin c 12.09.2018 12:59
0
1
898
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам нужен @ControllerAdvice. Вот как это использовать http://blog.codeleak.pl/2013/11/controlleradvice-improvements-in-spring.html

Ответ принят как подходящий

Вы можете использовать фильтры выполнять некоторую логику до или после запросов. В вашем случае более полезной была бы глобальная обработка ошибок:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = { IllegalArgumentException.class, IllegalStateException.class })
    protected ResponseEntity<Object> handleConflict(
      RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, 
          new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

Этот фрагмент взят из здесь.

Если вы хотите перехватить каждый запрос к конечной точке вашего контроллера до, он входит в метод контроллера, вам необходимо реализовать filter. Вы можете просмотреть этот руководство, чтобы понять, как реализовать фильтр.

Если вы хотите перехватить все исключения, возникающие в результате запросов к конечным точкам вашего контроллера (исключение могло быть создано где угодно - контроллер, служба, репозиторий и т. д.) В одном месте, тогда вам следует реализовать ExceptionHandler в ControllerAdvice. Простой пример будет таким:

@ControllerAdvice
public class ExceptionHandlerAdvice {

@ExceptionHandler(MismatchedInputException.class)
public ResponseEntity<Void> handleMismatchedInputException(MismatchedInputException e) {
    return ResponseEntity.status(BAD_REQUEST).build();
}

@ExceptionHandler(InvalidFormatException.class)
public ResponseEntity<Void> handleInvalidFormatException(InvalidFormatException e) {
    return ResponseEntity.status(UNPROCESSABLE_ENTITY).build();
}

}

Вышеупомянутое гарантирует, что любое исключение, указанное в обработчике исключений, будет перехвачено здесь, чтобы можно было оптимизировать ответ исключения от вашего REST API. Еще о том же здесь.

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