Вы можете реализовать собственный глобальный обработчик исключений, добавив фильтр:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionFilter extends OncePerRequestFilter {
private final ObjectMapper mapper = new ObjectMapper();
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (Exception ex) {
mapper.writeValue(response.getWriter(), new ErrorInfo("something bad happened"));
response.setContentType(MediaType.APPLICATION_JSON);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
response.getWriter().close();
response.getWriter().flush();
}
}
Информация об ошибках, отправляемая во внешний интерфейс, будет содержаться в классе ErrorInfo :
public class ErrorInfo {
// some custom fields as you wish
public ErrorInfo(String error) {
...
}
}
Как вы можете видеть выше, важно, чтобы фильтр выполнялся раньше всех других фильтров, добавив аннотацию @ Order с HIGHEST_PRECEDENCE в качестве значения. Если есть другие фильтры с таким же порядком, вы должны увеличить их порядок (например, заменив Ordered.HIGHEST_PRECEDENCE на Ordered.HIGHEST_PRECEDENCE + 1 ), чтобы они выполнялись после нашего фильтр обработки исключений.
Кроме того, вы должны убедиться, что ваш фильтр выполняется до цепочки фильтров Spring Security. Таким образом, вам нужно изменить порядок в цепочке фильтров Spring Security, установив для свойства security.filter-order в application.properties значение, превышающее порядок нашего GlobalExceptionFilter. :
security.filter-order=0
Когда исключение происходит где-то в нашей цепочке фильтров, оно будет перехвачено GlobalExceptionFilter , который, в свою очередь, создает объект ErrorInfo , содержащий информацию об ошибке, и сериализует ее, используя Джексон ObjectMapper . Наконец, ответ отправляется клиенту с указанным HTTP-статусом .