Показаны сообщения с ярлыком Filter. Показать все сообщения
Показаны сообщения с ярлыком Filter. Показать все сообщения

среда, 24 декабря 2008 г.

Библиотека urlrewrite

Недавно столкнулся с очень приятной библиотекой http://tuckey.org/urlrewrite/. Она представляет собой обычный фильтр который позволяет задавать свои настройки в хмл файле. Прелесть этой вещицы во первых в простоте (от первого знакомства до использования не более 5 минут), а во вторых в функционале (сейчас я с трудом себе могу представить как мои веб приложения обходились без нее).

Главная фича даной библиотеки: вы можете переформатировать запрос пользователя до не узнаваемости и затем перенаправить на нужный вам адрес. Это полезно во первых если вы хотите предоставить структурированые каким либо образом url-ы пользователю, во вторых, если вам просто нужно средиректить пользователя на другой адрес который имеет специфический формат и в третьих если ваши картинки, стили и ява скрипты запрашиваются клиентом по одному адресу, а вам по каким-либо причинам их удобно держать в другом.

Инсталяция: на сайте проэкта все детально описано, состоит из 3-х шагов: бросьте в папку WEB-INF/lib саму библиотеку urlrewrite.jar, в папку WEB-INF файл urlrewrite.xml (в котором вы будете описывать правила работы фильтра), и добавьте магические строки в web.xml:
1 <filter>
2 <filter-name>UrlRewriteFilter</filter-name>
3 <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
4 <init-param>
5 <param-name>logLevel</param-name>
6 <param-value>DEBUG</param-value>
7 </init-param>
8 <init-param>
9 <param-name>confReloadCheckInterval</param-name>
10 <param-value>5</param-value>
11 </init-param>
12 </filter>
13 <filter-mapping>
14 <filter-name>UrlRewriteFilter</filter-name>
15 <url-pattern>/*</url-pattern>
16 </filter-mapping>
в строке 6 указывается необязательный параметр - уровень вывода логов, а в строке 10 - интервал перечитывания файла urlrewrite.xml (даная конфигурация позволяет изменять его на лету, очень полезно на этапе разработки).

Конфигурирование файла urlrewrite.xml:
  1. может содержать несколько тегов rule, при этом они будут выполнятся один за другим сверху в низ
  2. для задания адресов используется Java Regular Expression. Кратко о синтаксисе можно прочитать например тут http://htmlweb.ru/java/regexp.php
  3. тег from - задает адреса на которые будет срабатывать фильтр
  4. тег to - указывает адрес куда будет перенаправлен пользователь (если используете redirect может пригодится внутренняя переменная %{context-path} - содержащая контекст вашего приложения).
    Пример:
    Если ваше приложение находится по адресу localhost/myapp то
    1 <to type="redirect">%{context-path}/index.jsp</to>
    пренаправит пользователя по адресу localhost/myapp/index.jsp
  5. condition - позволяет добавить дополнительные параметры, для того чтоб ограничить запросы на которые будет срабатывать фильтр.
    Пример:
    1 <condition type="request-uri" operator="notequal">/manager</condition>
    указывает что фильтр не должен срабатывать на запросы в которых встречается комбинация "/manager"
  6. set - позволяет записать информацыю в сессию, запрос, куки и т.д.
    Пример:
    1 <set name="publisherDomain" type="session">myDomain</set>
    записывает строку "myDomain" в переменную publisherDomain.
Маленький экскурс в регулярные выражения:
  • ^ - начало строки (пример: ^hi - значит что строка должна начинатся фразой "hi"
  • $ - конец строки

  • . - любой символ
  • [abc] - любой символ из заключенных в квадратные скобки
  • [^abc] - любой символ кроме заключенных в квадратные скобки
    можно также указать диапазон или тип символов

  • * - повторение символа 0 или более раз. (пример: ^/.* - строка начинается с / за которым следует любая комбинация символов)
  • + - как и * но обязательное повторение 1 раз или более
  • ? - повторение 0 или 1 раз

  • () -запомнить найденное выражение
  • $1, $2, ... - использовать запомненное выражение
    Пример:
    1 <rule>
    2 <from>^/(.+)$</from>
    3 <to type="redirect">/$1/login.html</to>
    4 </rule>
    Фильтр будет срабатывать на все адреса начинающиеся с "/" за которым следует хотя бы один символ и запоминать символы после "/". Т.е. если пользователь введет адрес /test, то фильтр перенаправит его на страницу /test/login.html
Для закрепления пример файла urlrewrite.xml:

1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
3
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd">

4
5 <urlrewrite>
6
7 <rule>
8 <from>^/portal$</from>
9 <to type="redirect">%{context-path}/portal/index.jsp</to>
10 </rule>
11
12 <rule>
13 <condition type="request-uri" operator="notequal">/portal</condition>
14 <condition type="request-uri" operator="notequal">/css</condition>
15 <condition type="request-uri" operator="notequal">/js</condition>
16 <condition type="request-uri" operator="notequal">/img</condition>
17 <condition type="request-uri" operator="notequal">/html</condition>
18 <from>^.*/(.*)/(.*)$</from>
19 <set name="publisherDomain" type="session">$1</set>
20 <to type="redirect">%{context-path}/portal/$2</to>
21 </rule>
22
23 </urlrewrite>
здесь первое правило будет срабатывать на запросы типа /portal и перенаправлять их на страницу /portal/index.jsp
Второе правило будет срабатывать на все остальные урлы кроме обращений связаных с загруской стилей, стат. страниц, картинок и т.д., далее оно будет вырезать выражение находящееся между первым и последним знаком "/"? и помещать его в сесию, а пользователя перенаправлять по адресу /myapp/portal/выражение_стоящее_за_последним_знаком_/

вторник, 23 декабря 2008 г.

Вызов спринговых бинов из фильтра

Если возникает необходимость вызова спринговых сервисов из фильтров можно использовать класс org.springframework.web.context.support.WebApplicationContextUtils, который позволяет обращатся к бинам по имени. По умолчанию имя бина совпадает с именем класа но начинается с маленькой буквы.
Например имеется бин PublisherService:

1 @Service
2 public class PublisherService {
3
4 @Autowired
5 private PubliherDAO publisherDAO;
6
7 //...
8 }

тогда его можно вызвать из фильтра следующим образом

1 public class MyFilter implements Filter {
2
3 private final Log log = LogFactory.getLog(getClass());
4
5 private PublisherService publisherService;
6
7 public void init(FilterConfig config) throws javax.servlet.ServletException {
8 if (null == publisherService) {
9 publisherService = (PublisherService) WebApplicationContextUtils
10 .getWebApplicationContext(config.getServletContext()).getBean(
11 "publisherService");
12 }
13 }
14
15 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
16 throws IOException, ServletException {
17
18 HttpServletRequest request = (HttpServletRequest) req;
19 HttpServletResponse response = (HttpServletResponse) resp;
20
21 // to do something with publisherService
22
23 chain.doFilter(req, resp);
24
25 }
26
27 public void destroy() {
28 }
29 }

web.xml файл при етом может выглядеть например так:

1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
4 xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation=
"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
6 version=
"2.4">

7
8 <display-name>MyApp</display-name>
9
10 <context-param>
11 <param-name>contextConfigLocation</param-name>
12 <param-value>
13 classpath:/**/applicationContext-*.xml,
14 </param-value>
15 </context-param>
16
17 <servlet>
18 <servlet-name>SpringMVC</servlet-name>
19 <servlet-class>
20 org.springframework.web.servlet.DispatcherServlet
21 </servlet-class>
22 <init-param>
23 <param-name>contextConfigLocation</param-name>
24 <param-value>classpath:**/SpringMVC-*.xml</param-value>
25 </init-param>
26 <load-on-startup>1</load-on-startup>
27 </servlet>
28
29 <context-param>
30 <param-name>log4jConfigLocation</param-name>
31 <param-value>/WEB-INF/classes/log4j.properties</param-value>
32 </context-param>
33
34 <filter>
35 <filter-name>MyFilter</filter-name>
36 <filter-class>mypack.MyFilter</filter-class>
37 </filter>
38 <filter-mapping>
39 <filter-name>MyFilter</filter-name>
40 <servlet-name>SpringMVC</servlet-name>
41 <dispatcher>REQUEST</dispatcher>
42 <dispatcher>FORWARD</dispatcher>
43 <dispatcher>INCLUDE</dispatcher>
44 </filter-mapping>
45
46 <servlet-mapping>
47 <servlet-name>SpringMVC</servlet-name>
48 <url-pattern>*.htm</url-pattern>
49 </servlet-mapping>
50
51 <welcome-file-list>
52 <welcome-file>index.html</welcome-file>
53 <welcome-file>index.jsp</welcome-file>
54 </welcome-file-list>
55
56 </web-app>