Фильтры в Java

Реализация интерфейса Filter позволяет создать объект, который может трансформировать заголовок и содержимое запроса клиента или ответа сервера. Фильтры не создают запрос или ответ, а только модифицируют его. Фильтр выполняет предварительную обработку запроса, прежде чем тот попадает в сервлет, с последующей (если необходимо) обработкой ответа, исходящего из сервлета. Фильтр может взаимодействовать с разными типами ресурсов, в частности
и с сервлетами, и с JSP-страницами.

Основные действия, которые может выполнить фильтр:

· перехват инициализации сервлета и определение содержания запроса, прежде чем сервлет будет инициализирован;

· блокировка дальнейшего прохождения пары request-response;

· изменение заголовка и данных запроса и ответа;

· взаимодействие с внешними ресурсами;

· построение цепочек фильтров;

· фильтрация более одного сервлета.

При программировании фильтров следует обратить внимание на интерфейсы Filter, FilterChain и FilterConfig из пакета javax.servlet. Сам фильтр определяется реализацией интерфейса Filter. Основным методом этого интерфейса является метод

void doFilter(ServletRequest req, ServletResponse res, FilterChain chain),

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

Кроме того, необходимо реализовать метод void init(FilterConfig config), который принимает параметры инициализации и настраивает конфигурационный объект фильтра FilterConfig. Метод destroy() вызывается при завершении работы фильтра, в тело которого помещаются команды освобождения используемых ресурсов.

Жизненный цикл фильтра начинается с однократного вызова метода init(), затем контейнер вызывает метод doFilter() столько раз, сколько запросов будет сделано непосредственно к данному фильтру. При отключении фильтра вызывается метод destroy().

С помощью метода doFilter() каждый фильтр получает текущий запрос и ответ, а также список фильтров FilterChain, предназначенных для обработки. Если в FilterChain не осталось необработанных фильтров, то продолжается передача запроса/ответа. Затем фильтр вызывает chain.doFilter() для передачи управления следующему фильтру.

В следующем примере рассматривается обращение к объекту request JSP-страницы demofilter.jsp и изменение значения атрибута запроса testName.

<!–пример # 7 : обращение к атрибуту : demofilter.jsp –>

<%@ page language="java" contentType="text/html;

charset=ISO-8859-5" pageEncoding="ISO-8859-5"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<html><head><title>Demo Filter</title></head>

<body>

<c:out value="Info from filter: ${info}"/><br>

<P>Дублирование действий фильтра смотреть в консоли</P>

</body></html>

Если фильтр не подключать, то переменная info значения не получит.

Реализация интерфейса Filter для поставленной задачи выглялит следующим образом:

/* пример # 8 : простая фильтрация значения атрибута : MyFilter.java */

package chapt21;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

public class MyFilter implements Filter {

private FilterConfig filterConfig;

public void init(final FilterConfig filterConfig) {

this.filterConfig = filterConfig;

}

public void doFilter(final ServletRequest request,

final ServletResponse response, FilterChain chain)

throws java.io.IOException,

javax.servlet.ServletException {

System.out.println("Вход в фильтр");

String value = "Simple Filter";

request.setAttribute("info", value);

chain.doFilter(request, response);

System.out.println("info = " + value);

System.out.println("Окончание фильтрa");

}

public void destroy() {

System.out.println("Уничтожение фильтрa");

}

}

Чтобы к фильтру происходило обращение, необходимо включить упоминание о фильтре и обрабатываемом ресурсе в элемент <webapp> дескрипторного файла web.xml в виде:

<filter>

<filter-name>simplefilter</filter-name>

<filter-class>chapt21.MyFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>simplefilter</filter-name>

<url-pattern>/demofilter.jsp</url-pattern>

</filter-mapping>

Фильтр может модифицировать ответ сервера клиенту. Одним из распространенных приемов использования фильтра является модификация коди­ровки ответа. Когда сервлет посылает ответ клиенту через поток PrintWriter, используется установленная в сервлете кодировка. В следующем примере рассматривается фильтр, изменяющий кодировку ответа на кириллицу UTF-8.

// пример # 9 : фильтр, устанавливающий кодировку запроса : SetCharFilter.java

package chapt21;

import java.io.IOException;

import javax.servlet.*;

public class SetCharFilter implements Filter {

private FilterConfig filterConfig = null;

public void init(FilterConfig config)

throws ServletException {

this.filterConfig = config;

}

public void doFilter(ServletRequest request,

ServletResponse response, FilterChain next)

throws IOException, ServletException {

// чтение кодировки из запроса

String encoding = request.getCharacterEncoding();

System.out.println(encoding);

// установка UTF-8, если не установлена

if (!"UTF-8".equalsIgnorCase(encoding))

response.setCharacterEncoding("UTF-8");

next.doFilter(request, response);

}

public void destroy() {

}

}

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

<filter>

<filter-name>setCharFilter</filter-name>

<filter-class>chapt21.SetCharFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>setCharFilter</filter-name>

<url-pattern>/DemoCharServlet</url-pattern>

</filtermapping>

Таким образом, ответ сервлета DemoCharServlet будет в необходимой кодировке.

/*пример # 10 : без установки кодировки ответ сервлета будет нечитаем :
DemoCharServlet.java*/

package chapt21;

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class DemoCharServlet extends HttpServlet {

public void init() throws ServletException {

}

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.print("Кодировка установлена успешно!");

}

public void destroy() {

super.destroy();

}

}

В результате в браузер будет выведено:

Кодировка установлена успешно!

Источник: Java. Промышленное программирование : практ. пособие / И.Н. Блинов, В.С. Романчик. – Минск : УниверсалПресс, 2007. – 704 с

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

3 коммент. »

 
  • Антон says:

    Хотелось бы понять, как перехватывать запрос к определенным сервлетам, и если надо отсылать на необходимую страницу.

  • Denis says:

    #1

    setCharFilter

    chapt21.SetCharFilter

    setCharFilter

    /DemoCharServlet

    вроде как это и есть оно или я не понял вопроса!

  • Lightning says:

    #1
    Вопрос не понятен мне, вроде как объявление фильтра в веб.хмл с указанием сервлета на который он переходит.
    или же используй ресспонсе.сендРедирект(“url”)

 

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100