Servlet Filters
-
Idea is that you want to filter calls to a servlet first through a filter (or chain of multiple filters) to perform some kind of "checking" task before the servlet is invoked.
-
Examples - authentication, login (Authentication ---e.g. Facebook application authentication to get access to social data/channels!!!!)
-
Create a filter by extending javax.servlet.Filter class and setting up @WebFilter annotationle to have a filter class(es) associated with it that the server will invoke first.
-
Look here for an example associated with our facebook app in java.
Servlet 3.* + standard for Filter Declaration
-
NOW use annotation @WebFilter
The following Filter says anytime the URL /hello is invoked call the doFilter() method of TestFilter class and pass the parameters of message=Servlet says:
-
package example; import java.io.*; import javax.servlet.*; @WebFilter (value="/hello", initParams=({ @WebInitParam(name="message", value="Servlet says: ") }) ) public TestFilter implements Filter { private FilterConfig _filterConfig; public void init(FilterConfig filterConfig) throws ServletException { _filterConfig = filterConfig; } public void doFilter(ServletRequest req,ServletResponse res, FilterChain chain) throws ServletException, IOException { PrintWriter out = res.getWriter(); out.print(_filterConfig.getInitParameter("message")); } public void destroy() { // destroy } }
Metadata specified in WebFilter are available via FilterConfig object, so the output of http://localhost:8080/${app-name}/hello should render text where the Servlet says: is produced by the Filter and the Hello Servlet that is involed by the URL above produces the Hello World!
OUTPUT of f http://localhost:8080/${app-name}/hello
Servlet says: Hello World!
Another @WebFilter example
@WebFilter(filterName = "TimeOfDayFilter", urlPatterns = {"/*"}, initParams = { @WebInitParam(name = "mood", value = "awake")} )
The @WebFilter annotation has the following attributes
boolean | asyncSupported Declares whether the filter supports asynchronous operation mode. |
optional |
java.lang.String | description The description of the filter |
optional |
DispatcherType[] | dispatcherTypes The dispatcher types to which the filter applies |
optional |
java.lang.String | displayName The display name of the filter |
optional |
java.lang.String | filterName The name of the filter |
optional |
WebInitParam[] | initParams The init parameters of the filter |
optional |
java.lang.String | largeIcon The large-icon of the filter |
loptional |
java.lang.String[] | servletNames The names of the servlets to which the filter applies. (if not given will match directly to URL patterns only) |
optional (possibly) |
java.lang.String | smallIcon The small-icon of the filter |
optional |
java.lang.String[] | urlPatterns The URL patterns to which the filter applies |
REQUIRED WHEN NO value set **( Use the value attribute when the only attribute on the annotation is the URL pattern; use the urlPatterns attribute when other attributes are also used.) |
java.lang.String[] | value The URL patterns to which the filter applies |
REQUIRED**( Use the value attribute when the only attribute on the annotation is the URL pattern; use the urlPatterns attribute when other attributes are also used.) |
Specifying Filter Parameters
Depending on IDE you use, you can setup Filter's class parameters in a GUI as shown below for Eclipse
Make a new fileter New->Filter
Lets change the name to MyFilter2 and click on Add to a Filter Mapping...lets map to a servelt called DummyServlet (meaning
any time that DummyServlet is invoked first MyFilter2 will be executed.
Now we are ready to hit the Finish button
Here is the start of the new autogenerated Filter code we get....
it says in the @WebFilter annotation that any time /MyFilter2 or DummyServlet is invoked
it will first run the MyFIlter2 (doFilter() method)
package grewe.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* Servlet Filter implementation class MyFilter2
*/
@WebFilter(urlPatterns = { "/MyFilter2" }, servletNames = { "DummyServlet" })
public class MyFilter2 implements Filter {
/**
* Default constructor.
*/
public MyFilter2() {
***************and more***********
Specifying Filter Mappings
-
The filters are invoked in the order in which filter mappings appear in the filter mapping list of a WAR.
You specify a filter mapping list for a WAR in its deployment descriptor -
If you want to log every request to a web application, you map the "hit counter filter" (this is a filter that simply increments a counter) to the URL pattern /*.
-
You can map a filter to one or more web resources, and you can map more than one filter to a web resource.
filter F1 is mapped to servlets S1, S2, and S3;
filter F2 is mapped to servlet S2;
filter F3 is mapped to servlets S1 and S2.
Specifying Filter Chain order of Filters
-
Recall that a filter chain is one of the objects passed to the doFilter method of a filter.
-
This chain is formed indirectly by means of filter mappings.
Option 1 -- you may be able to set in container specific deployment file (see specs for your container if possible)
-
The order of the filters in the chain is the same as the order in which filter mappings appear in the web application deployment descriptor.
-
EXAMPLE: When a filter is mapped to servlet S1, the web container invokes the doFilter method of F1. The doFilter method of each filter in S1’s filter chain is invoked by the preceding filter in the chain by means of the chain.doFilter method. Because S1’s filter chain contains filters F1 and F3, F1’s call to chain.doFilter invokes the doFilter method of filter F3. When F3’s doFilter method completes, control returns to F1’s doFilter method.
- can not find any evidence for glassfish
Option 2 -- you have to go to Old style use of web.xml file for deployment (see below)
Option 3 -- IF YOU DONT CARE the order then simply define them with @WebFilter and don't worry
OLD Servlet standard for declaring Filter classes used web.xml file
Example a Filter being defined to be the class net.thlievweb.facebook.FacebbokAuthFilter used for Facebook authentication
<web-app> <display-name> Facebook Application </display-name> <filter> <filter-name> FaceBookAuthFilter </filter-name> <filter-class> net.theliveweb.facebook.FaceBookAuthFilter </filter-class> <init-param> <param-name>api_key</param-name> <param-value>[api-key]</param-value> </init-param> <init-param> <param-name>secret_key</param-name> <param-value>[secret-key]</param-value> </init-param> </filter> <filter-mapping> <filter-name>FaceBookAuthFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> </web-app>