English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Краткое рассмотрение фильтра Filter в Java

Filter简介

Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

Он主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

Функция Filter

Интерцепция HttpServletRequest до того, как она достигнет Servlet. В зависимости от необходимости проверьте HttpServletRequest, также можно изменить заголовки и данные HttpServletRequest.

Интерцепция HttpServletResponse до того, как она достигнет клиента. В зависимости от необходимости проверьте HttpServletResponse, также можно изменить заголовки и данные HttpServletResponse.

Как использовать Filter для реализации функции拦截

В интерфейсе Filter есть метод doFilter. После того как разработчик напишет Filter и настроит拦截哪个 веб-ресурс, веб-сервер каждый раз будет вызывать метод doFilter фильтра перед вызовом метода service веб-ресурса, поэтому код в этом методе可以达到 следующим целями:

Выполнение的一段 кода перед вызовом целевого ресурса.

Вызов целевого ресурса (т.е. позволяет ли пользователю访问 веб-ресурс).

При вызове метода doFilter веб-сервер передает объект filterChain, который является одним из важнейших объектов интерфейса filter, он также предоставляет метод doFilter. Разработчик может решить, нужно ли вызывать этот метод. Если вызывается этот метод, веб-сервер вызовет метод service веб-ресурса, то есть веб-ресурс будет доступен, в противном случае веб-ресурс не будет доступен.

Два шага для разработки Filter

Написание java класса, реализующего интерфейс Filter, и реализация его метода doFilter.

 В файле web.xml регистрируется написанный фильтр класса и устанавливаются ресурсы, которые он может拦截.

Введение в конфигурацию web.xml:

  • <filter> определяет фильтр.
  • <filter-name> используется для определения имени фильтра, содержимое этого элемента не может быть пустым.
  • <filter-class> элемент используется для определения полного квалифицированного имени класса фильтра.
  • <init-param> элемент используется для определения инициализационных параметров фильтра, его подэлемент <param-name> определяет имя параметра, <param-value> определяет значение параметра.
  • В фильтре можно использовать объект интерфейса FilterConfig для доступа к инициализационным параметрам.
  • <filter-mapping> элемент используется для настройки ресурсов, которые отвечает за фильтр. Ресурсы,拦截的 фильтром, можно определить двумя способами: имя сервлета и путь запроса к ресурсу
  • Подэлемент <filter-name> используется для установки регистрационного имени фильтра. Это значение должно быть именем фильтра, объявленным в элементе <filter>.
  • <url-pattern> устанавливает путь запроса,拦截аемый фильтром (образец URL, связанный с фильтром)
  • <servlet-name> определяет имя servlet,拦截 фильтром.
  • <dispatcher> определяет способ вызова ресурсов,拦截аемых фильтром, servlet контейнером, может быть одним из REQUEST, INCLUDE, FORWARD и ERROR, по умолчанию REQUEST. Пользователь может установить несколько подэлементов <dispatcher>, чтобы指定 различные способы拦截 фильтра для ресурсов.
  • Значения и значения, которые можно установить для подэлемента <dispatcher>
  • ЗАПРОС: Когда пользователь напрямую访问 страницу, веб-контейнер вызовет фильтр. Если целевой ресурс доступен через методы include() или forward() RequestDispatcher, то фильтр не вызывается.
  • ВКЛЮЧИТЬ: Если целевой ресурс доступен через метод include() RequestDispatcher, то этот фильтр будет вызван. В противном случае фильтр не вызывается.
  • ПЕРЕДОВАТЬ: Если целевой ресурс доступен через метод forward() RequestDispatcher, то этот фильтр будет вызван, в противном случае фильтр не вызывается.
  • ОШИБКА: Если целевой ресурс вызывается через механизмы обработки исключений declarative, то этот фильтр будет вызван. В противном случае фильтр не вызывается.

Фильтр-цепь

В веб-приложении можно разработать несколько фильтров, которые вместе называют фильтр-цепь.

Веб-сервер определяет порядок вызова фильтров, зарегистрированных в файле web.xml, и решает, какой фильтр вызвать первым. Когда вызывается метод doFilter первого фильтра, веб-сервер создает объект FilterChain, представляющий фильтр, и передает его методу doFilter. В методе doFilter, если разработчик вызывает метод doFilter объекта FilterChain, веб-сервер проверяет, есть ли еще фильтры в FilterChain, и если есть, то вызывается следующий фильтр, если нет, то вызывается целевый ресурс.

Жизненный цикл фильтра

public void init(FilterConfig filterConfig) throws ServletException;//初始化

Как и наше приложение Servlet, создание и уничтожение Filter обеспечивается веб-сервером. При запуске веб-приложения веб-сервер создает экземпляр Filter и вызывает метод init, читая конфигурацию из web.xml, чтобы выполнить инициализацию объекта и подготовить его к перехвату последующих запросов пользователей (объект Filter создается один раз, метод init также вызывается один раз). Разработчик может получить объект FilterConfig, представляющий текущую конфигурацию фильтра, через параметры метода init.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; // Перехват запроса

Этот метод выполняет фактическую операцию фильтрации. При запросе клиента на доступ к URL, связанному с фильтром, фильтр Servlet выполняет метод doFilter. Параметр FilterChain используется для доступа к следующим фильтрам.

public void destroy(); // Уничтожение

Объект Filter остается в памяти, и уничтожается только при удалении веб-приложения или остановке сервера. Этот метод вызывается перед удалением объекта Filter из контейнера. Этот метод выполняется только один раз в жизни фильтра и используется для освобождения ресурсов, используемых фильтром.

Интерфейс FilterConfig

При конфигурации фильтра пользователь может определить一些 инициализационные параметры для фильтра. При инсталлировании объекта Filter веб-контейнер вызывает метод init, передавая в него объект filterConfig, который содержит инициализационные параметры фильтра. Таким образом, разработчик может получить следующее через методы объекта filterConfig:

String getFilterName(); // Получает имя фильтра. 
String getInitParameter(String name); // Возвращает значение инициализационного параметра с указанным именем в описании развертывания. Если параметр не существует, возвращает null. 
Enumeration getInitParameterNames(); // Возвращает множество итераторов с именами всех инициализационных параметров фильтра. 
public ServletContext getServletContext(); // Возвращает ссылку на объект контекста Servlet.

Пример использования фильтра

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

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

сначала настроить в web.xml

<filter>
  <filter-name>SessionFilter</filter-name>
  <filter-class>com.action.login.SessionFilter</filter-class>
  <init-param>
    <param-name>logonStrings</param-name><!-- Не фильтровать страницы входа -->
    <param-value>/project/index.jsp;login.do</param-value>
  </init-param>
  <init-param>
    <param-name>includeStrings</param-name><!-- Фильтрация только для указанных суффиксов параметров -->
    <param-value>.do;.jsp</param-value>
  </init-param>
  <init-param>
    <param-name>redirectPath</param-name><!-- Не пройдено, перейти к странице входа -->
    <param-value>/index.jsp</param-value>
  </init-param>
  <init-param>
    <param-name>disabletestfilter</param-name><!-- Y: фильтр неактивен -->
    <param-value>N</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>SessionFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

затем пишем FilterServlet

package com.action.login;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/*
 /*  Определение, был ли пользователь авторизован, если нет, то выходим из системы
 */
public class SessionFilter implements Filter {
  public FilterConfig config;
  public void destroy() {
    this.config = null;
  }
  public static boolean isContains(String container, String[] regx) {
    boolean result = false;
    for (int i = 0; i < regx.length; i++) {
      if (container.indexOf(regx[i]) != -1) {
        return true;
      }
    }
    return result;
  }
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest hrequest = (HttpServletRequest)request;
    HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);
    String logonStrings = config.getInitParameter("logonStrings");    // страница для входа в систему
    String includeStrings = config.getInitParameter("includeStrings");  // параметр суффикса ресурсов для фильтрации
    String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath"); // без доступа к странице перехода
    String disabletestfilter = config.getInitParameter("disabletestfilter"); // Фильтр активен ли
    if (disabletestfilter.toUpperCase().equals("Y")) { // Фильтр не действует
      chain.doFilter(request, response);
      return;
    }
    String[] logonList = logonStrings.split(";");
    String[] includeList = includeStrings.split(";");
    if (!this.isContains(hrequest.getRequestURI(), includeList)) { // Фильтровать только указанные параметры фильтрации
      chain.doFilter(request, response);
      return;
    }
    if (this.isContains(hrequest.getRequestURI(), logonList)) { // Не фильтровать страницы входа
      chain.doFilter(request, response);
      return;
    }
    String user = (String) hrequest.getSession().getAttribute("useronly"); // Проверка входа пользователя
    if (user == null) {
      wrapper.sendRedirect(redirectPath);
      return;
    } else {
      chain.doFilter(request, response);
      return;
    }
  }
  public void init(FilterConfig filterConfig) throws ServletException {
    config = filterConfig;
  }
}

Таким образом, все запросы пользователей должны быть проверены на этом Filter для проверки их аутентификации.

Фильтр предотвращения китайских символов

Проект использует фреймворк Spring. Когда на переднем JSP-странице и Java-коде используется различный набор символов для кодирования, может возникнуть проблема с неправильной кодировкой данных формы или китайских файлов во время загрузки/скачивания. В этом случае можно использовать этот фильтр.

<filter>
  <filter-name>encoding</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name><!--для указания конкретного charset-->
    <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
    <param-name>forceEncoding</param-name><!--true: если request указал charset, то используется encoding; false: если request уже указал charset, то encoding не используется-->
    <param-value>false</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>encoding</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Это конец всего содержимого статьи, мы надеемся, что это поможет вам в изучении, и希望大家多多支持呐喊教程。

Декларация: контент этой статьи был взят из Интернета, авторские права принадлежат соответствующему автору, материал был предоставлен пользователями Интернета по их собственной инициативе и загружен на этот сайт. Этот сайт не имеет права собственности на этот материал, не производил его редактирование и не несет ответственности за него. Если вы обнаружите материал,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу notice#oldtoolbag.com (при отправке письма замените # на @) для отчета и предоставьте соответствующие доказательства. Если после проверки будет установлено, что материал нарушил права на интеллектуальную собственность, этот сайт немедленно удалил涉嫌侵权的内容。

Рекомендуется к просмотру