Я хочу использовать общий способ управления кодами ошибок 5xx, скажем конкретно, случай, когда db не работает во всем моем весеннем приложении. Я хочу красивую ошибку json вместо трассировки стека.
Для контроллеров у меня есть @ControllerAdvice
класс для различных исключений, и это также улавливает случай, когда db останавливается в середине запроса. Но это еще не все. У меня также есть настраиваемое CorsFilter
расширение, OncePerRequestFilter
и когда я звоню, doFilter
я получаю, CannotGetJdbcConnectionException
и он не будет управляться @ControllerAdvice
. Я прочитал в Интернете несколько вещей, которые только сбили меня с толку.
Так что у меня много вопросов:
- Мне нужно реализовать собственный фильтр? Я нашел,
ExceptionTranslationFilter
но это только ручкиAuthenticationException
илиAccessDeniedException
. - Я думал о реализации своего собственного
HandlerExceptionResolver
, но это заставило меня усомниться в том, что у меня нет настраиваемого исключения для управления, должен быть более очевидный способ, чем этот. Я также попытался добавить try / catch и вызвать реализациюHandlerExceptionResolver
(должно быть достаточно хорошо, в моем исключении нет ничего особенного), но это ничего не возвращает в ответ, я получаю статус 200 и пустое тело.
Есть ли хороший способ справиться с этим? Спасибо
java
spring
spring-security
Копелица
источник
источник
Ответы:
Вот что я сделал:
Я прочитал основы о фильтрах здесь , и я понял, что мне нужно , чтобы создать пользовательский фильтр , который будет первым в цепочке фильтров и попробовать поймать поймать все исключения времени выполнения , которые могут возникнуть там. Затем мне нужно создать json вручную и поместить его в ответ.
Итак, вот мой собственный фильтр:
А затем я добавил его в web.xml перед файлом
CorsFilter
. И это работает!источник
Я хотел предложить решение, основанное на ответе @kopelitsa . Основные отличия заключаются в следующем:
HandlerExceptionResolver
.Во-первых, вам нужно убедиться, что у вас есть класс, который обрабатывает исключения, возникающие в обычном RestController / Controller (класс, помеченный
@RestControllerAdvice
или,@ControllerAdvice
и метод (ы), аннотированный@ExceptionHandler
). Это обрабатывает ваши исключения, возникающие в контроллере. Вот пример использования RestControllerAdvice:Чтобы повторно использовать это поведение в цепочке фильтров Spring Security, вам необходимо определить фильтр и подключить его к вашей конфигурации безопасности. Фильтр должен перенаправить исключение на указанную выше обработку исключений. Вот пример:
Затем созданный фильтр необходимо добавить в SecurityConfiguration. Вам нужно подключить его к цепочке очень рано, потому что все предыдущие исключения фильтра не будут перехвачены. В моем случае было разумно добавить его перед расширением
LogoutFilter
. См. Цепочку фильтров по умолчанию и ее порядок в официальной документации . Вот пример:источник
Я сам столкнулся с этой проблемой и выполнил следующие шаги, чтобы повторно использовать свой
ExceptionController
, помеченный@ControllerAdvise
дляExceptions
добавления в зарегистрированный фильтр.Очевидно, существует много способов обработки исключения, но в моем случае я хотел, чтобы исключение обрабатывалось мной,
ExceptionController
потому что я упрямый, а также потому, что я не хочу копировать / вставлять тот же код (т.е. у меня есть некоторая обработка / ведение журнала код вExceptionController
). Я хотел бы вернуть красивыйJSON
ответ, как и остальные исключения, созданные не из фильтра.Как бы то ни было, мне удалось воспользоваться своим
ExceptionHandler
и мне пришлось сделать немного больше, как показано ниже в шагах:Шаги
@ControllerAdvise
например, MyExceptionControllerОбразец кода
А теперь пример Spring Controller, который обрабатывает
Exception
в обычных случаях (т.е. исключения, которые обычно не выбрасываются на уровне фильтра, который мы хотим использовать для исключений, созданных в фильтре)Совместное использование решения с теми, кто хочет использовать
ExceptionController
дляExceptions
добавления фильтра.источник
@Component
класс и использовать ее в фильтре и в Контроллер.answer
это один из способов! Я не утверждал, что это лучший способ. Спасибо, что поделились своим беспокойством @psv Я уверен, что сообщество оценит решение, которое выИтак, вот что я сделал на основе объединения вышеперечисленных ответов ... У нас уже был
GlobalExceptionHandler
аннотированный@ControllerAdvice
и я также хотел найти способ повторно использовать этот код для обработки исключений, поступающих из фильтров.Самым простым решением, которое я смог найти, было оставить обработчик исключений в покое и реализовать контроллер ошибок следующим образом:
Таким образом, любые ошибки, вызванные исключениями, сначала проходят через
ErrorController
обработчик исключений и перенаправляются в обработчик исключений, повторно генерируя их из@Controller
контекста, тогда как любые другие ошибки (не вызванные непосредственно исключением) проходят черезErrorController
без изменений.Есть ли причины, по которым это на самом деле плохая идея?
источник
@Override public String getErrorPath() { return null; }
Если вам нужен общий способ, вы можете определить страницу ошибки в web.xml:
И добавьте отображение в Spring MVC:
источник
Это мое решение, переопределив Spring Boot / обработчик ошибок по умолчанию
источник
Просто чтобы дополнить другие предоставленные прекрасные ответы, так как я слишком недавно хотел иметь один компонент обработки ошибок / исключений в простом приложении SpringBoot, содержащем фильтры, которые могут вызывать исключения, с другими исключениями, которые могут быть выброшены из методов контроллера.
К счастью, кажется, что нет ничего, что могло бы помешать вам объединить совет контроллера с переопределением обработчика ошибок Spring по умолчанию, чтобы обеспечить согласованные полезные данные ответа, позволить вам делиться логикой, проверять исключения из фильтров, перехватывать исключения, создаваемые конкретными службами и т.
Например
источник
Если вы хотите проверить состояние приложения и в случае возникновения проблемы вернуть ошибку HTTP, я бы предложил фильтр. Фильтр ниже обрабатывает все HTTP-запросы. Самое короткое решение в Spring Boot с фильтром javax.
В реализации могут быть разные условия. В моем случае applicationManager проверяет, готово ли приложение.
источник
Прочитав различные методы, предложенные в приведенных выше ответах, я решил обрабатывать исключения аутентификации с помощью настраиваемого фильтра. Мне удалось обработать статус ответа и коды, используя класс ответа на ошибку, используя следующий метод.
Я создал настраиваемый фильтр и изменил свою конфигурацию безопасности с помощью метода addFilterAfter и добавил после класса CorsFilter.
SecurityConfig класс
ErrorResponse класс
источник
Вы можете использовать следующий метод внутри блока catch:
Обратите внимание, что вы можете использовать любой код HttpStatus и настраиваемое сообщение.
источник
Это странно, потому что @ControllerAdvice должен работать, вы ловите правильное исключение?
Также попробуйте перехватить это исключение в CorsFilter и отправить ошибку 500, что-то вроде этого
источник
Filter
может не быть пойман,@ControllerAdvice
потому что в него может не попастьDispatcherServlet
.Для этого не нужно создавать собственный фильтр. Мы решили эту проблему, создав пользовательские исключения, которые расширяют ServletException (которое выбрасывается из метода doFilter, показанного в объявлении). Затем они перехватываются и обрабатываются нашим глобальным обработчиком ошибок.
редактировать: грамматика
источник