Home » Пример фильтра сервлета в Java
Пример фильтра сервлета в Java

Пример фильтра сервлета в Java

Если ты когда-нибудь возился с Java-сервлетами, то наверняка сталкивался с задачей: “А как бы мне перехватить все запросы к моему приложению и что-нибудь с ними сделать?” Например, логировать, проверять авторизацию, подменять заголовки или даже блокировать доступ к определённым ресурсам. Вот тут на сцену выходит фильтр сервлета — штука, без которой не обходится ни один уважающий себя Java-веб-проект. В этой статье разберёмся, что такое фильтр сервлета, как он работает, как его быстро прикрутить к своему проекту, и какие фишки можно выжать из этого механизма. Всё с примерами, схемами и практическими советами, чтобы ты мог не только понять, но и сразу внедрить у себя на сервере.

Как это работает? — Простыми словами о фильтрах сервлетов

Фильтр сервлета (Servlet Filter) — это специальный компонент в Java EE (Jakarta EE), который внедряется в цепочку обработки HTTP-запросов и ответов. Он может перехватывать, изменять или даже блокировать запросы и ответы, проходящие через твой сервер. Фильтры не генерируют контент сами по себе (это задача сервлетов), но могут влиять на то, как этот контент обрабатывается.

  • Где живёт фильтр? — Между клиентом (браузером, ботом, скриптом) и сервлетом/ресурсом.
  • Что может делать? — Логировать, проверять авторизацию, сжимать/декомпрессировать данные, переписывать URL, фильтровать вредоносные запросы, внедрять CORS-заголовки и многое другое.
  • Когда вызывается? — Каждый раз, когда приходит HTTP-запрос, подходящий под его mapping.

Вся магия происходит в методе doFilter(). Фильтр получает на вход ServletRequest и ServletResponse, а также цепочку фильтров (FilterChain). Ты можешь что-то сделать до передачи запроса дальше, после — или вообще не передавать его, если надо заблокировать.

Как быстро и просто всё настроить?

Давай по шагам, чтобы не было лишней теории. Вот как внедрить фильтр в свой Java-веб-проект (например, на Tomcat, Jetty, WildFly — не принципиально).

  1. Создай класс фильтра
    Реализуй интерфейс javax.servlet.Filter (или jakarta.servlet.Filter в новых версиях).

    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    @WebFilter("/*") // фильтруем все запросы
    public class LoggingFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            System.out.println("Запрос: " + request.getRemoteAddr());
            chain.doFilter(request, response); // передаём дальше
            System.out.println("Ответ отправлен");
        }
    }
        
    • @WebFilter(“/*”) — фильтр на все запросы. Можно указать конкретные URL-шаблоны.
    • В doFilter() — твоя логика до и после chain.doFilter().
  2. Зарегистрируй фильтр

    • Через аннотацию @WebFilter (современно, удобно).
    • Или через web.xml (олдскул, но иногда нужно для гибкости):
    
    <filter>
        <filter-name>LoggingFilter</filter-name>
        <filter-class>com.example.LoggingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoggingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
        
  3. Перезапусти сервер

    • Если ты на Tomcat — systemctl restart tomcat или просто перезапусти через панель.
    • Проверь логи — должны появиться твои сообщения.

Примеры, схемы, практические советы

Давай разберём несколько кейсов — от простого к сложному. Плюс — что делать, если что-то пошло не так.

Кейс Плюсы Минусы Рекомендации
Логирование всех запросов
  • Просто реализовать
  • Видно, кто и что запрашивает
  • Может засорить логи
  • Проблемы с GDPR (персональные данные)
  • Логируй только нужные данные
  • Очищай логи регулярно
Авторизация по токену
  • Централизованный контроль доступа
  • Можно быстро менять логику
  • Ошибки — и сервис недоступен всем
  • Сложнее тестировать
  • Пиши тесты на фильтр
  • Делай исключения для health-check
Сжатие ответа (GZIP)
  • Экономия трафика
  • Быстрее загрузка страниц
  • Нагрузка на CPU
  • Иногда ломает бинарные данные
  • Проверяй тип контента
  • Отключай для больших файлов
Блокировка по IP
  • Просто реализовать
  • Мгновенная реакция на злоумышленников
  • Можно заблокировать легитимных юзеров
  • IP легко подделать
  • Используй списки доверенных IP
  • Логируй все блокировки

Полезные команды и примеры кода

Вот несколько типовых фильтров, которые можно скопировать и сразу использовать:


// Фильтр для CORS (разрешить доступ с других доменов)
@WebFilter("/*")
public class CorsFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        chain.doFilter(req, res);
    }
}

// Фильтр для блокировки по IP
@WebFilter("/*")
public class BlockIpFilter implements Filter {
    private static final Set<String> BLOCKED_IPS = Set.of("192.168.1.100", "10.0.0.1");
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        String ip = req.getRemoteAddr();
        if (BLOCKED_IPS.contains(ip)) {
            ((HttpServletResponse) res).sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied");
            return;
        }
        chain.doFilter(req, res);
    }
}

// Фильтр для сжатия ответа (GZIP)
@WebFilter("/*")
public class GzipFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        if (acceptsGzip((HttpServletRequest) req)) {
            GzipResponseWrapper gzipResponse = new GzipResponseWrapper(response);
            chain.doFilter(req, gzipResponse);
            gzipResponse.close();
        } else {
            chain.doFilter(req, res);
        }
    }
    private boolean acceptsGzip(HttpServletRequest req) {
        String ae = req.getHeader("Accept-Encoding");
        return ae != null && ae.contains("gzip");
    }
}

Для продвинутых: можно использовать сторонние библиотеки для фильтрации, например, HTTP-Proxy-Servlet или Logbook для логирования HTTP-трафика.

Похожие решения, программы и утилиты

  • Spring Boot Filters — если ты на Spring, фильтры реализуются через OncePerRequestFilter или HandlerInterceptor. Гибко, удобно, но чуть сложнее для новичков.
  • nginx/apache mod_security — фильтрация на уровне веб-сервера. Быстрее, но не так гибко, как на уровне приложения.
  • Servlet Listener — похож на фильтр, но работает с жизненным циклом приложения, а не с запросами.

Если нужен VPS или выделенный сервер для экспериментов — заказать VPS или выделенный сервер можно прямо здесь.

Статистика и сравнение с другими решениями

Решение Гибкость Производительность Простота внедрения Где применять
Servlet Filter Высокая Средняя Средняя Java-приложения, кастомная логика
nginx/apache фильтрация Средняя Высокая Высокая Быстрая блокировка, статические сайты
Spring Interceptor Очень высокая Средняя Средняя Spring-проекты, сложная логика
WAF (Web Application Firewall) Средняя Высокая Средняя Безопасность, защита от атак

Интересные факты и нестандартные способы использования

  • Можно использовать фильтры для A/B тестирования — подменять ответы для разных групп пользователей.
  • Фильтр может внедрять кастомные заголовки (например, X-Request-ID для трекинга запросов).
  • Через фильтр можно реализовать rate limiting (ограничение количества запросов с одного IP).
  • Фильтры отлично подходят для внедрения кэширования на уровне приложения.
  • Можно использовать фильтр для автоматической конвертации данных (например, JSON в XML и обратно).

Какие новые возможности открываются? Автоматизация и скрипты

Фильтры сервлетов — это не только про безопасность и логирование. С их помощью можно:

  • Автоматически внедрять метрики (например, время обработки запроса, размер ответа) — удобно для мониторинга.
  • Реализовать динамическую маршрутизацию (например, для blue-green деплоймента или canary релизов).
  • Интегрировать с CI/CD: фильтр может автоматически блокировать доступ к приложению во время деплоя.
  • Скриптовать тестирование безопасности — например, фильтр, который логирует подозрительные запросы для дальнейшего анализа.
  • Внедрять кастомные политики CORS, CSP, HSTS — всё через пару строк кода.

Вывод — заключение и рекомендации

Фильтр сервлета — это универсальный инструмент для любого Java-веб-приложения. Он позволяет гибко управлять потоком запросов и ответов, внедрять логику безопасности, мониторинга, оптимизации и автоматизации прямо на уровне приложения. Если ты хочешь быстро решить задачу логирования, авторизации, ограничения доступа или внедрения кастомных заголовков — фильтр сервлета подойдёт идеально. Главное — не переборщить с количеством фильтров и не забывать про производительность. Для сложных сценариев лучше использовать специализированные решения (WAF, nginx, Spring Interceptor), но для большинства задач фильтр сервлета — это быстро, просто и надёжно.

Если ты только начинаешь работать с Java-серверами — попробуй реализовать свой первый фильтр прямо сейчас. Это отличный способ понять, как работает веб-приложение изнутри и получить полный контроль над входящими и исходящими данными. А если нужен сервер для экспериментов — VPS или выделенный сервер всегда к твоим услугам.

Официальная документация по фильтрам сервлетов: https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0.html#filters

Пробуй, экспериментируй, автоматизируй — и пусть твой сервер всегда будет под контролем!


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked