过滤订单和web.xml内容

时间:2017-04-14 13:24:56

标签: eclipse web.xml servlet-filters

嗯,直截了当: 我创建了 - 使用Eclipse - 两个过滤器(Filter1和Filter2)和一个servlet(DisplayHeader)来查看执行的过滤器顺序。 我使用Tomcat 8.5作为目标运行时。

新/动态网站项目/     与上下文根/     并检查“生成web.xml delpoyment描述符”

Filter1在执行时打印“我是过滤器1”,并将其“链接”到特定的servlet“DisplayHeader”。 Filter2它是2兄弟而不是1的双胞胎兄弟。 DisplayHeader servlet映射到/ DisplayHeader。

为清晰起见,下面是Filter1代码

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;

@WebFilter(
        urlPatterns = {"/Filter1"}, 
        servletNames = {"DisplayHeader"}
        )
public class Filter1 implements Filter {

    /**
     * Default constructor. 
     */
    public Filter1() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see Filter#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // TODO Auto-generated method stub
        // place your code here
        System.out.println("I'm Filter 1");

        // pass the request along the filter chain
        chain.doFilter(request, response);
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig fConfig) throws ServletException {
        // TODO Auto-generated method stub
    }

}

好吧,当我在Tomcat(Tomcat v8.5)上运行servlet时,它会打印

I'm Filter 1
I'm Filter 2

表示Filter1在Filter2之前执行。

我读到过滤器的执行顺序来自web.xml文件中的映射顺序, 所以我希望在web.xml文件中找到类似

的地方
<filter-mapping>
<filter-name>Filter1</filter-name>
<url-pattern>/DisplayHeader</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>Filter2</filter-name>
<url-pattern>/DisplayHeader</url-pattern>
</filter-mapping>

我应该按顺序颠倒......

问题是:当我打开我的项目的web.xml(从项目浏览器,见下图)文件时,我只看到这个:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>SetFilterOrder</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

web.xml location in the explorer

我是否错过了正确的web.xml文件路径,或者此web.xml是使用“生成web.xml delpoyment描述符”选项的结果?

2 个答案:

答案 0 :(得分:1)

根据我的经验,过滤器链从根向上运行。

说你有:

domain.com/loggedInArea/UserProfile/Address.jsp. 

如果每个级别都有一个过滤器,它们将从&#34;最短的&#34;开始执行。 “&#34;最长&#34;:

的网址
@WebFilter("/*")
@WebFilter("/loggedInArea/*")
@WebFilter("/loggedInArea/UserProfile/*")
@WebFilter("/loggedInArea/UserProfile/Address.jsp")

您无法使用URL过滤器通配符,因为您可以使用它们,例如搜索文件名。所以,你可以搜索

Addr*.jsp

但您无法使用它来指定WebFilter网址

如果我理解正确,你提到的例子就是你为练习WebFilters而创建的东西 - 绝对没问题 - 而不是你正在研究的项目的要求。我无法想象一个现实生活中的例子,您需要确定执行过滤器的顺序而不是URL级别。

你不能

@WebFilter("/loggedInArea/UserProfile/Address.*p")
@WebFilter("/loggedInArea/UserProfile/Addr*sp")

因为您必须使用特定的文件名,它们将是互斥的。

如果您有两个具有相同网址的不同过滤器

@WebFilter("/loggedInArea/UserProfile/*")
@WebFilter("/loggedInArea/UserProfile/*")

(Tomcat甚至可能会拒绝启动,如果你有这个,不确定)然后这一切都应该压缩成一个单独的过滤器,你可以从中控制流量。

答案 1 :(得分:0)

从我所做的阅读中看起来并不像Servlet 3.0提供了一种通过注释定义订单的方法。因此,要定义您必须使用web.xml的顺序。它可能使用的顺序可能是字母顺序,也可能只是运气不好,哪些类在进行注释扫描时首先出现。您可以通过过滤器名称或过滤器类名来测试它。最终你不能依赖于此。确定您似乎必须恢复到web.xml。

参考文献:
How to define servlet filter order of execution using annotations in WAR

http://www.concretepage.com/java-ee/jsp-servlet/how-to-use-filter-in-servlet-3-with-webfilter-annotation

http://javabycode.com/java-frameworks/servlet-jsp/filter-servlet-3-using-webfilter-annotation-example.html