Используя Tomcat, @WebFilter не работает с <filter-mapping> внутри web.xml
Здесь работает 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)
...
Я выполнил ответ этого вопроса, но это не работает для меня.
Вот зависимости моего веб-приложения:
<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>
EDIT: У меня проблема только при использовании Tomcat (7.0.14). Glassfish в порядке.
Ответы
Ответ 1
Это ошибка в Tomcat 7. Я сообщил об этом как issue 53354.
Как невозможно указать порядок вызова в @WebFilter
, пользователи вынуждены явно указывать <filter-mapping>
в web.xml. Это работает в сочетании с @WebFilter(filterName)
в Glassfish и JBoss AS следующим образом:
@WebFilter(filterName="filter1")
public class Filter1 implements Filter {}
@WebFilter(filterName="filter2")
public class Filter2 implements Filter {}
с
<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>
Однако он не работает в Tomcat 7.0.27 со следующим запутанным исключением (установлен <url-pattern>
)
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>
в любом случае.
Ответ 2
Вы должны указать цель для сервлет-фильтра. Либо укажите значение "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