2012-06-01 61 views
7

这里的一个工作的web.xml工作:使用Tomcat,@WebFilter不与<滤波器映射>内的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0"> 

    <session-config> 
     <session-timeout>30</session-timeout> 
    </session-config> 

    <filter> 
     <filter-name>rememberMeCookieFilter</filter-name> 
     <filter-class>be.example.fun.jsp.filters.RememberMeCookieFilter</filter-class> 
    </filter> 

    <filter> 
     <filter-name>mustBeSignedInFilter</filter-name> 
     <filter-class>be.example.fun.jsp.filters.MustBeSignedInFilter</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>rememberMeCookieFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter-mapping> 
     <filter-name>mustBeSignedInFilter</filter-name> 
     <url-pattern>/private/*</url-pattern> 
    </filter-mapping> 
</web-app> 

当我除去<filter>元素,并且使用以下注释代替:

@WebFilter(filterName="rememberMeCookieFilter") 
public class RememberMeCookieFilter implements Filter 

@WebFilter(filterName="mustBeSignedInFilter") 
public class MustBeSignedInFilter implements Filter 

则在Tomcat 7.0.14使我有以下错误:

java.lang.IllegalArgumentException: Filter mapping must specify either a <url-pattern> or a <servlet-name> 
    at org.apache.catalina.core.StandardContext.validateFilterMap(StandardContext.java:2956) 
    at org.apache.catalina.core.StandardContext.addFilterMap(StandardContext.java:2915) 
    at org.apache.catalina.deploy.WebXml.configureContext(WebXml.java:1180) 
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1270) 
     ... 

我跟着this question的回答,但这对我不起作用。

这里是我的web应用程序的依赖关系:

<dependencies> 
     <!-- SLF4J (+ LOGBack) for logging --> 
     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>slf4j-api</artifactId> 
      <version>1.6.4</version> 
     </dependency> 
     <dependency> 
      <groupId>ch.qos.logback</groupId> 
      <artifactId>logback-core</artifactId> 
      <version>1.0.0</version> 
     </dependency> 
     <dependency> 
      <groupId>ch.qos.logback</groupId> 
      <artifactId>logback-classic</artifactId> 
      <version>1.0.0</version> 
     </dependency> 
     <dependency> 
      <groupId>org.codehaus.groovy</groupId> 
      <artifactId>groovy</artifactId> 
      <version>1.8.3</version> 
     </dependency> 

     <!-- The servlet API that I installed in my local repo --> 
     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>servlet-api</artifactId> 
      <version>3.0</version> 
      <type>jar</type> 
      <scope>provided</scope> 
      <!--optional>false</optional--> 
     </dependency> 

     <!-- JUnit for testing --> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.8.2</version> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 

编辑:使用Tomcat(7.0.14)时,我只有这个问题。 Glassfish很好。

+0

你可以尝试使用最新版本的Tomcat 7吗?当前版本是7.0.27。 –

+0

我做到了这一点,同样的问题。 ;) – AndrewBourgeois

回答

11

这是Tomcat 7中的一个bug。我报告它为issue 53354

As it's not possible to specify the invocation order in a @WebFilter , users are forced to explicitly specify <filter-mapping> in web.xml. This works in combination with a @WebFilter(filterName) in Glassfish and JBoss AS as follows:

@WebFilter(filterName="filter1") 
public class Filter1 implements Filter {} 

@WebFilter(filterName="filter2") 
public class Filter2 implements Filter {} 

with

<filter-mapping> 
    <filter-name>filter1</filter-name> 
    <url-pattern>/url1/*</url-pattern> 
</filter-mapping> 
<filter-mapping> 
    <filter-name>filter2</filter-name> 
    <url-pattern>/url2/*</url-pattern> 
</filter-mapping> 

However it fails in Tomcat 7.0.27 with the following confusing exception (the <url-pattern>is been set)

Caused by: java.lang.IllegalArgumentException: Filter mapping must specify either a <url-pattern> or a <servlet-name> 
    at org.apache.catalina.core.StandardContext.validateFilterMap(StandardContext.java:3009) 
    at org.apache.catalina.core.StandardContext.addFilterMap(StandardContext.java:2968) 
    at org.apache.catalina.deploy.WebXml.configureContext(WebXml.java:1207) 
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1294) 
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:855) 
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:345) 
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) 
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    ... 7 more 

在此期间你最好的选择是使用Glassfish的或JBoss AS中,而不是,或通过<filter>反正注册的过滤器。

+0

我可以使用元素,因为我正在为自己的学习做这件事。为什么这个问题现在才被发现? Servlet 3.0已经出现了一段时间,Tomcat 7也是这样,这是一个非常基本的特性......(我只是刚开始学习servlets)。人们是否放弃其他过滤器或...? – AndrewBourgeois

+0

不知道。也许是因为人们没有意识到这一点。或者可能是因为排序对他们无关紧要。或者,也许是因为他们没有使用Tomcat来处理那些具有多个过滤器的非常小的web应用程序,而这些过滤器的排序很重要。或者也许是因为他们没有觉得值得付出努力。等等,谁知道。 – BalusC

+2

供参考:已[固定](https://issues.apache.org/bugzilla/show_bug.cgi?id=53354#c1)[标记](http://stackoverflow.com/users/1299005/mark-托马斯)几秒前。将在7.0.28及以后。 – BalusC

2

您必须为Servlet过滤器指定一个目标。提供'servletNames'或'urlPatterns'的值。

http://docs.oracle.com/javaee/6/api/javax/servlet/annotation/WebFilter.html

例如

@WebFilter(filterName="mustBeSignedInFilter", urlPatterns={ "/signed/in/path/*" }) 
public class MustBeSignedInFilter implements Filter 
+0

我只是从我的web.xml中删除元素,而不是元素。正如在下面的问题中回答,它应该工作:http://stackoverflow.com/questions/6560969/how-to-define-servlet-filter-order-of-execution-using-annotations。它只在我将它部署在Glassfish环境中时才起作用。 – AndrewBourgeois

相关问题