Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Simple Servlet Filter Question  RSS feed

 
Mike London
Ranch Hand
Posts: 1476
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

I can't seem to find any simple examples of how to set up a Servlet FilterChain.

I'm thinking you might list two <filter-name> classes in the project's web.xml under the <filter> tag where each <filter-name> would be one filter in the chain.

The basic thing I'm trying to do is have the first filter do something, then pass along the request to the next filter and finally to the Servlet.

Also, in the doFilter method, there's a chain object. I'm assuming that when you call chain.doFilter(request, response), the internals of the web.xml handle the chaining automatically (that is, calling the next servlet filter works automatically).

Can anyone please clarify exactly how I need to define multiple FilterChain servlet filters (particularly in web.xml)?

Thanks.

Mike
 
Jesus Angeles
Ranch Hand
Posts: 2070
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can find great examples in Marty Hall's books. I think it is titled, Core Servlets and JSPs, and the other one is , More Servlets and JSPs. They have lots of samples.
 
Ben Souther
Sheriff
Posts: 13411
Firefox Browser Redhat VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike,
Take a look at SRV.6.2.1 in the servlet spec.
There is a link in my signature.

It's a pretty quick and straight forward read and should answer your question.
 
Mike London
Ranch Hand
Posts: 1476
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have the "More Servlets" book, but I don't see where Marty actually uses a FilterChain.

Isn't this simple to explain/answer without having to look at a spec?

Thanks in advance.

Mike
 
Ben Souther
Sheriff
Posts: 13411
Firefox Browser Redhat VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Mike London:

Isn't this simple to explain/answer without having to look at a spec?

You're making it sound like looking at the spec is a bad thing.
Here...

Step 4: The filter may invoke the next entity in the filter chain. The next
entity may be another filter, or if the filter making the invocation is the last
filter configured in the deployment descriptor for this chain, the next entity
is the target Web resource. The invocation of the next entity is effected by
calling the doFilter method on the FilterChain object, and passing in the
request and response with which it was called or passing in wrapped
versions it may have created.
The filter chain�s implementation of the doFilter method, provided by the
container, must locate the next entity in the filter chain and invoke its
doFilter method, passing in the appropriate request and response objects.



In other words, just create multiple filters and enter the mappings to yoru deployment descriptor (web.xml) in the order that you want them called. The the container will take care of chaining them together for you.
 
Mike London
Ranch Hand
Posts: 1476
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ben,

Thanks!!!

My concern was thinking that the FilterChain needed to be (conceptually in web.xml) like a linked list -- where the next filter in the chain somehow needs to reference the last one.... to form a "list" (or chain).

But, what you're saying sounds even better. Just create a bunch of "independent" filters (with no reference to each other) within web.xml and magic happens by the container.

Nice.

Thanks for your reply.

- Mike
 
Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper
Posts: 4968
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, the filters are created independent of each other. Then they are simply linked together in the web.xml file. Depending upon how you code your doFilter method, assuming you always call the next filter in the chain, the link of filters will be processed in order.

Here's a little tutorial on creating Filters, along with the code used in the example:


Creating ServletFilters Multimedia Tutorial

<filter>
<description>
</description>
<display-name>
AmericanFilter</display-name>
<filter-name>AmericanFilter</filter-name>
<filter-class>com.examscam.web.filter.AmericanFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AmericanFilter</filter-name>
<url-pattern>/AmericanFilter</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AmericanFilter</filter-name>
<servlet-name>CountrySnooper</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
 
Mike London
Ranch Hand
Posts: 1476
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm...

Well if I define a single filter and a servlet, I can call the Servlet from the URL like this: http://localhost/servlet/MyHeader.

Works fine.

But, when I add the second filter to web.xml, everything stops working. All I get from Tomcat is that the requested resource is not available (one of my favorite messages... <g> .

Each Servlet Filter calls the chain.doFilter as shown below.

chain.doFilter(request, response);

Clearly the way I'm doing it is breaking the chain and I'm never getting to the servlet with the second filter in the chain.

I'm not referencing the second filter (by name) from the first filter as I thought this was automatic.

Here's my complete web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
[url=http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">]http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">[/url]

<!-- Register the logging servlet filter -->
<filter>
<filter-name>Logger</filter-name>
<filter-class>net.somedomain.filters.Logger</filter-class>
</filter>

<!--Apply this filter to all Servlets and JSP pages-->
<filter-mapping>
<filter-name>Logger</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>Header</filter-name>
<filter-class>net.somedomain.filters.Header</filter-class>
</filter>

<!--Apply this filter to all Servlets and JSP pages-->
<filter-mapping>
<filter-name>Header</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
<description>The Final Item in the Chain...The Actual Servlet!</description>
<display-name>Allow modification of the header of any page</display-name>
<servlet-name>MyHeader</servlet-name>
<servlet-class>net.somedomain.servlets.MyHeader</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyHeader</servlet-name>
<url-pattern>/servlet/MyHeader</url-pattern>
</servlet-mapping>

</web-app>

Any ideas?

Thanks.

-- Mike
 
Mike London
Ranch Hand
Posts: 1476
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, got it working.

My problem was that I had forgotten to include the "implements Filter" in second class in the filter chain.

Oops.

Thanks to all for these terrific replies!!!

- Mike
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!