Читать «Java 7 (Наиболее полное руководство)» онлайн - страница 422

Ильдар Шаукатович Хабибуллин

}

}

Фильтр класса SetCharEncFilter, описанный в листинге 26.7, очень прост. Он извлекает из запроса req заголовок Content-Type методом getContentType (). Если такой заголовок есть, то он пытается извлечь из него кодировку. Если это не удается, то берет кодировку из своего начального параметра "encoding". Затем он заносит кодировку в ответ resp методом setCharacterEncoding (String) и передает управление следующему фильтру.

Всякий разработчик, желающий улучшить определение кодировки, может переопределить метод selectEncoding (), извлекая информацию из других заголовков, например:

User-Agent, Accept-Language, Accept-Charset, Content-Language.

В более сложных случаях понадобится расширить объекты req и resp. Вот тут-то и пригодятся классы HttpServletRequestWrapper и HttpServletResponseWrapper. Дополнительные свойства запроса и ответа можно занести в расширения этих классов-оболочек и использовать их в фильтре по такой схеме.

public class MyRequestHandler extends HttpServletRequestWrapper{

public MyRequestHandler(HttpServletRequest req){ super(req);

// ...

}

// ...

}

public class MyResponseHandler extends HttpServletResponseWrapper{

public MyResponseHandler(HttpServletResponse resp){ super(resp);

// ...

}

// ...

}@WebFilter(urlPatterns={"/*"})

public class MyFilter implements Filter{

private MyRequestHandler mreq; private MyResponseHandler mresp;

@Override

public void init(FilterConfig conf){

// ...

}

@Override

public void doFilter(ServletRequest req,

ServletResponse resp,

FilterChain chain){

mreq = new MyRequestHandler((HttpServletRequest)req); mresp = new MyResponseHandler((HttpServletResponse)resp);

// Действия до перехода к следующему фильтру.

chain.doFilter(mreq, mresp);

// Действия после возврата из сервлета и фильтров.

}

@Override

public void destroy(){ mreq = null; mresp = null;

}

}

После того как класс-фильтр написан и скомпилирован, его надо установить в контейнер и приписать (map) к одному или нескольким сервлетам. Это выполняется утилитой установки или средствами IDE, в которых указывается имя фильтра, его начальные параметры и сервлет, к которому приписывается фильтр. Утилита установки заносит сведения о фильтре в конфигурационный файл web.xml в элемент <filter>. Это можно сделать и вручную. Приписка фильтра к сервлету отмечается внутри элемента <filtermapping> парой вложенных элементов <filter-name> и <servlet-name>. Например:

<filter-mapping>

<filter-name>MyFilter</filter-name>

<servlet-name>RegServlet</servlet-name>

</filter-mapping>

Фильтр можно приписать не только сервлетам, но и другим ресурсам. Для этого записывается элемент <url-pattern>, например после

<filter-mapping>

<filter-name>MyFilter</filter-name>

<url-pattern>*.html</url-pattern>

</filter-mapping>

фильтр будет применен ко всем вызовам документов HTML.

Порядок фильтров в цепочке соответствует порядку элементов <filter-mapping> в конфигурационном файле web.xml. При обращении клиента к сервлету контейнер сначала отыскивает фильтры и последовательно выполняет их, а уж потом запускает сервлет. После работы сервлета его ответ проходит цепочку фильтров в обратном порядке.