servlet
servlet copied to clipboard
Clarify behaviour when the same filter is matched by several filter-mapping elements
The chapter 6.2.4 Configuration of Filters in a Web Application defines how a container builds the chain of filters to be applied to a particular request URI.
My question is what should happen if there are several matching filter-mappings for the same filter (either by different
An example:
If the requested URI is "/view/bar.do", does the filter have to be called twice?
My own reading is that "a)" (multiple calls) is what is implied by that chapter, but I would like this to be mentioned explicitly.
If actually the requirement is "b)" (single call), then I would like someone to clarify what mapping takes priority when there is both an url-pattern and a servlet-name match. As the servlet-name mappings are processed first, it seems that the servlet-name mapping wins, but it is confusing as those filters are positioned later in the resulting filter chain than the ones mapped by url-patterns.
In Tomcat 7 the "b)" behaviour was implemented but with url-patterns having the priority, stemming from the following issue: https://issues.apache.org/bugzilla/show_bug.cgi?id=49922
- Issue Imported From: https://github.com/javaee/servlet-spec/issues/52
- Original Issue Raised By:@glassfishrobot
- Original Issue Assigned To: @shingwaichan
@glassfishrobot Commented Reported by kkolinko
@glassfishrobot Commented janbartel said: Interestingly jetty shows two different behaviours. If you define a single filter mapping with multiple url-patterns as the example above, we will only apply the filter once. If, however, you defined different filter mappings for each url-pattern, we would apply the filter once for each mapping. Obviously consistent behaviour would be desirable.
Section 6.2.4 does mention breaking a single filter mapping with multiple url-patterns into multiple filter-mappings - which would lend some support to calling the filter multiple times - however the wording mentions breaking a single filter-mapping into multiple filter-mappings only in the context of there being at least one servlet-name present:
"If a filter mapping contains both
So the current wording does not make clear if filter mappings with multiple url-patterns should be broken out into separate mappings. Furthermore, it does not make clear whether multiple mappings to the same filter, whether originating from multiple matching url-patterns and/or a servlet-name, result in multiple invocations of the same Filter in the filter chain.
In considering a wording fix and clarification of multiple vs single invocation, we need to bear in mind the resultant filter chain ordering. Consider the following:
The possible filter chain outcomes for a request path of "/foo/bar/x.jsp" are:
-
With multiple applications of the same filter (and multiple url-patterns within a single mapping are treated as multiple mappings): AFilter (/foo/) AFilter(.jsp) BFilter (.jsp) AFilter (/foo/bar/)
-
Single application of matching filter, first wins: AFilter (/foo/) BFilter (.jsp)
-
Single application of matching filter, last wins: BFilter (.jsp) AFilter(/foo/bar/)
Option 1) has the advantage of being strictly consistent. Whilst with 2) and 3) it's simply an arbitrary choice, and moreover leaves users with parts of their web.xml that are effectively being ignored.
Incidentally, I think the wording of Section 8.2.3 point 2.a. is wrong. It says "Filters that match a request are chained in the order in which they are declared in the web.xml". In fact it is not the order of the declaration of the
@glassfishrobot Commented This issue was imported from java.net JIRA SERVLET_SPEC-52
Here is another example that illustrates this question:
<servlet>
<servlet-name>Servlet0</servlet-name>
<servlet-class>org.example.ZeroServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet0</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>X</filter-name>
<filter-class>org.example.XFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>X</filter-name>
<servlet-name>Servlet0</servlet-name>
<url-pattern>*.txt</url-pattern>
<url-pattern>/foo/*</url-pattern>
</filter-mapping>
Should a request to /foo/bar.txt invoke filter X once, twice or three times?
Section 6.2.4 of of the 4.0 spec says that combined filter mapping is equivalent to:
<filter-mapping>
<filter-name>X</filter-name>
<servlet-name>Servlet0</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>X</filter-name>
<url-pattern>*.txt</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>X</filter-name>
<url-pattern>/foo/*</url-pattern>
</filter-mapping>
It then tells us that the order is by the url-patterns in the order they are declared and then the filtername, but it is silent of what to do if a mapping has mutliple matches that apply.
See also #318 for a related clarification