Какой паттерн реализует метод doFilter у фильтра в Java
Что проверяют
Знаете ли вы, как устроена обработка запроса в Servlet API, и можете ли назвать паттерн без подсказки. Следом почти всегда спрашивают, что будет, если фильтр не вызовет chain.doFilter, и как задать порядок фильтров в Spring Boot.
Как отвечать
Короткий ответ: цепочка обязанностей (Chain of Responsibility). В каталоге Core J2EE Patterns та же схема описана как Intercepting Filter. Дальше покажите механику:
Filter: интерфейс изjakarta.servlet(до Jakarta EE 9 пакет называлсяjavax.servlet). МетодdoFilter(request, response, chain)получает запрос и ссылку на остаток цепочки;FilterChain: знает следующее звено. Вызовchain.doFilter(request, response)передаёт управление дальше, последним звеном идёт сам сервлет;- код до и после вызова: всё, что стоит до
chain.doFilter, работает на входе, всё после работает на обратном пути, когда ответ уже сформирован. Так делают замер времени, заголовки, аудит; - обрыв цепочки: фильтр вправе не звать
chain.doFilterи сам отдать 401 или 403. Это и есть классическое «обработал сам или передал дальше».
Хорошо добавить, что в классической цепочке запрос обычно обрабатывает одно звено, а в фильтрах каждое делает свою часть и передаёт дальше. Ещё одно попадание в тему: HttpServletRequestWrapper подменяет запрос обёрткой, это уже декоратор внутри цепочки. Из Spring вспомните OncePerRequestFilter, порядок через @Order или FilterRegistrationBean.setOrder() и FilterChainProxy в Spring Security, который держит свою внутреннюю цепочку фильтров.
Где спотыкаются
Называют основным ответом декоратор. Обёртка запроса действительно декоратор, но передача управления через FilterChain это цепочка обязанностей.
Забывают вызвать chain.doFilter в одной из веток if. Запрос не доходит до контроллера, клиент получает пустой ответ с кодом 200, и ищут такое долго.
Читают тело запроса прямо в фильтре ради логирования. Поток ввода читается один раз, и контроллер получает пустое тело. Нужна обёртка вроде ContentCachingRequestWrapper, а закешированное тело читают уже после chain.doFilter.