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