Может ли фильтр сервлетов определить, какой сервлет будет обрабатывать запрос? - PullRequest
4 голосов
/ 04 апреля 2011

Я пишу фильтр, который выполняет ведение журнала, и мне нужно отключить это ведение журнала, если запрос заканчивается в определенном сервлете.

Может ли фильтр узнать, какой сервлет обработает запрос?

Ответы [ 3 ]

6 голосов
/ 04 апреля 2011

Возможно, вы захотите настроить отображение фильтра сервлета, чтобы оно не запускалось в случае запросов на конкретный сервлет в целом.

Пример конфигурации может выглядеть так, если предположить, что существует один DefaultServlet, на который не должен воздействовать фильтр идва других сервлета FirstServlet и SecondServlet, которые должны быть затронуты.

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <servlet-name>FirstServlet</servlet-name>
</filter-mapping>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <servlet-name>SecondServlet</servlet-name>
</filter-mapping>
0 голосов
/ 04 апреля 2011

Я всегда думаю, что вы должны иметь возможность делать исключения для шаблонов URL в файле web.xml, например. если бы вы могли сделать что-то вроде этого:

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>
        <match>/resources/*</match>
        <except>/resouces/images/blah.jpg</except>
    </url-pattern>

но ты не можешь, так что это тебе не поможет!

У вас, очевидно, есть доступ к URL-адресу в фильтре через объект запроса, чтобы вы могли сделать что-то вроде этого:

public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
                        FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest)sRequest;

    if(!request.getRequestURI.equals("/resources/images/blah.jpg")) {
        doLogging();
    }

    chain.doFilter();
}

(здесь жестко запрограммировано, но вы, вероятно, прочитали бы его из файла свойств), хотя это может оказаться бесполезным, поскольку вы упоминали сервлеты в своем запросе, а не шаблоны URL.

РЕДАКТИРОВАТЬ: другая мысль. Если вы не возражаете заняться регистрацией после завершения сервлета, вы можете сделать что-то вроде этого:

public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
                        FilterChain chain) throws IOException, ServletException {

    sRequest.setAttribute("DO_LOGGING", new Boolean(true));
    chain.doFilter();

    Boolean doLogging = (Boolean)sRequest.getAttribute("DO_LOGGING");
    if(doLogging) {
        doLogging();
    }
}

и ваш сервлет, который вы хотите исключить из журнала, может просто установить для этого атрибута значение false.

public void doGet(HttpServletRequest req, 
                    HttpServletResponse res) throws IOException {

   req.setAttribute("DO_LOGGING", new Boolean(false));
   // other stuff
}
0 голосов
/ 04 апреля 2011

Вы можете назначить шаблон URL, который нужно отфильтровать, например,

<filter>
        <filter-name>Admin</filter-name>
        <filter-class>com.nil.FilterDemo.AdminFilter</filter-class>
</filter>

<filter-mapping>
        <filter-name>Admin</filter-name>
        <url-pattern>/admin/*</url-pattern>
</filter-mapping>

Этот фильтр будет запускаться для каждого отдельного запроса, обрабатываемого механизмом сервлета с / admin mapping.

...