Прежде всего, позвольте мне объяснить, почему ваши попытки с аспектом и советом контроллера не увенчались успехом.
Поток идет следующим образом (значительно упрощенный, но все же, надеюсь, «глубокий», чтобы объяснить суть):
- Запрос попадает в Интернет (например, tomcat)
- Tomcat преобразует необработанный текст HTTP-запроса (полезную нагрузку) в java классы, представляющие запрос http (HttpServletRequest et c )
- Если указано, запрос проходит через javax.servlet.Filter-s, которые работают с «необработанными» объектами запроса.
- Tomcat находит сервлет для обработки запроса. В этом случае его Spring MVC's DispatcherServlet
- Tomcat передает выполнение DispatcherServlet. В этот момент приходит пружина.
- DispatcherServlet находит, что контроллер вызывается
- DispatcherServlet «понимает», как преобразовать данные из необработанного запроса в параметры метода, указанного в контроллере ( что должно быть сопоставлено с «путем», как преобразовать тело и т. д.). Например, если ожидается, что он будет JSON, Джексон будет использоваться для фактического преобразования.
- Контроллер вызывается
Теперь, обновляя часть AOP: рекомендация AOP охватывает ваш контроллер эффективно предоставляя прокси "неотличимый" от реального контроллера. Таким образом, этот прокси может быть вызван (прозрачно для Spring MVC) во время шага "8"
. Это «счастливый путь». Однако что произойдет, если запрос будет неправильным?
- Если это не Http-запрос, он не выполнится на шаге 2 и явно не достигнет шага 8
- Если он действителен HTTP-запрос, но не отображается правильно (например, неправильный путь отображения URL-адреса и т. д. c). DispatcherServlet не найдет соответствующий контроллер для его обработки, поэтому он не выполнится во время шага "6"
- Если JSON полезная нагрузка неверна, шаг 7 завершится неудачей.
В любом случае он не достигнет шага 8, и именно поэтому ваш совет не вызывается
Теперь о @ControllerAdvice
. Это «специальный» механизм обработки исключений весной MVC, который помогает правильно отображать исключения, возникающие внутри контроллера (или класс, к которому обращается контроллер, например, service, Dao, et c.). Поскольку поток даже не достиг контроллера, здесь он в значительной степени не имеет значения.
Теперь с точки зрения или разрешения:
Есть две основные абстракции, которые вы можете попробовать сделать программно:
- Фильтр javax.servlet , чтобы сделать это в виде веб-контейнера
- HandlerInterceptorAdapter , чтобы сделать это в пружине MVC way
В обоих случаях вам придется иметь дело с необработанным запросом. Вот пример пружинного mvc способа:
@Component
public class LoggingInterceptor
extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) {
return true; // called before the actual controller is invoked
}
@Override
public void afterCompletion(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
// called after the controller has processed the request,
// so you might log the request here
}
}
Чтобы правильно зарегистрировать и отобразить перехватчик, используйте WebMvcConfigurer
. В целом см. этот пример
Другие решения включают в себя:
- Spring Boot Actuator имеет конечную точку, которая регистрирует 50 последних запросов
- Tomcat (если вы используете tomcat, например) имеет специальный Valve, который может регистрировать запросы (доступ к стилю журнала). Смотрите эту тему , например