Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Tomcat, @WebFilter doesn't work with <filter-mapping> inside web.xml

Here's a working 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>

When I remove the <filter> elements and use the following annotations instead:

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

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

Then Tomcat 7.0.14 gives me the following error:

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)
        ...

I followed the answer of this question, but that doesn't work for me.

Here are the dependencies of my web application:

<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: I only have the issue when using Tomcat (7.0.14). Glassfish is fine.

like image 394
AndrewBourgeois Avatar asked Jun 01 '12 20:06

AndrewBourgeois


People also ask

What is Web xml filter?

Filters in web. xml are used for filtering functionality of the Java web application. They intercept the requests from client before they try to access the resource. They manipulate the responses from the server and sent to the client.


2 Answers

It's a bug in Tomcat 7. I reported it as 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

In the meanwhile your best bet is to use Glassfish or JBoss AS instead, or to register the filters by <filter> anyway.

like image 126
BalusC Avatar answered Sep 29 '22 12:09

BalusC


You must specify a target for the Servlet Filter. Either provide a value for 'servletNames' or 'urlPatterns'.

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

e.g.

@WebFilter(filterName="mustBeSignedInFilter", urlPatterns={ "/signed/in/path/*" })
public class MustBeSignedInFilter implements Filter
like image 40
Pidster Avatar answered Sep 29 '22 12:09

Pidster