The Servlet filters

The Servlet filters are components that can intercept an incoming request and outgoing response before it gets to a Java Servlet. The filters can be chained together through the configuration of the web deployment descriptor or through the annotations. Filters do not normally generate the content, rather they are designed to transform, modify, or adapt a request around a resource. The filters can be used for logging, security, and performance monitoring.

A Servlet filter implements the javax.servlet.Filter interface. A Servlet filter implements the doFilter() method, which takes three arguments: ServletRequest, ServletResponse, and javax.servlet.FilterChain.

FilterChain is a simple interface with one method doFilter(), which is the way to transfer the control to the next filter in the chain.

Let's review, together, a working example as follows:

package je7hb.servlets.simple;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Date;

@WebFilter(filterName = "MySimpleFilterLogger", urlPatterns = {"/*"}, initParams = {@WebInitParam(name = "fruit", value = "Pear"),})
public class SimpleLoggingFilter implements Filter {
  private FilterConfig filterConfig;
  
  public void init(FilterConfig filterConfig) {
    System.out.printf("init() on %s
"+ "Metadata filter name=%s
", getClass().getSimpleName(), filterConfig.getFilterName());
    this.filterConfig = filterConfig;
    }
  
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
  throws IOException, ServletException {
    System.out.printf("doFilter() on %s at %s
", this.getClass().getSimpleName(), new Date());
    System.out.printf("init parameter on 'fruit' is %s
", filterConfig.getInitParameter("fruit"));
    filterChain.doFilter(request, response);
    }
  
  public void destroy() {
    System.out.printf("destroy() on %s
", getClass().getSimpleName());
    }
  }

This filter SimpleLoggingFilter is annotated by the name MySimpleFilterLogger with the URL patterns (/*) such that it intercepts all the requests. The class dumps the output to the console output. A filter has initialization and destruction methods, which web container invokes as the web application starts up or shuts down accordingly.

Inside the doFilter() method, executing the filterChain.doFilter() method is the critical part, because that call passes the control back to web container, and then it causes the execution of the next filter in line or the actual resource.

The Servlet filter annotation attributes

A table of the @WebFilter attributes is as follows:

Attribute

Type

Description

Default Value

filterName

String

Defines the name of the filter.

Empty

Value

String []

Defines the URL patterns of the filter.

None

urlPatterns

String []

Defines the URL patterns of the filter.

None

initParams

WebInitParam []

The initial parameters of the filter.

None

servletNames

String []

Specifies names of Servlets to which the web container applies the filter.

None

dispatcherTypes

DispatcherTypes []

Specifies the dispatcher types that the filter applies. A filter can intercept requests to {FORWARD, INCLUDE, REQUEST, ASYNC, ERROR} dispatchers.

REQUEST

displayName

String

The display name of the filter.

None

description

String

The description for a filter.

Empty string

smallIcon

String

Specifies a path to a small icon.

None

largeIcon

String

Specifies a path to a large icon.

None

The Servlet filter XML configuration

If you prefer not to declare the annotations, then the filter must be declared in a deployment descriptor, the web.xml file. An XML fragment that configures the filter is as follows:

<filter>
  <filter-name>MySimpleFilterLogger</filter-name>
    <filter-class>
      je7hb.servlets.simple.SimpleLoggingFilter
    </filter-class>
    <init-param>
      <param-name>fruit</param-name>
      <param-value>strawberry</param-value>
    </init-param>
</filter>

<filter-mapping>
  <filter-name>MySimpleFilterLogger</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<filter> and <filter-mapping> are direct subelements of the <web-app> element, and they are visually similar to the Servlet mappings.

The <filter> element declares the filter name, fully qualified class name, and optionally the initialization parameters. The <filter-mapping> element associates a filter name with a set of the URL patterns.

To implement a security servlet filter, the logic of the doFilter() method would change to only execute the next filter on completion of a check.

The following code is an example of securing a resource with a Servlet filter:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
throws IOException, ServletException {
  HttpServletRequest req2 = (HttpServletRequest)req;
  HttpServletResponse res2 = (HttpServletResponse)res;
  if (req2.getUserPrincipal().getName() .equals("admin")) {
    filterChain.doFilter(req, res);
    }
  else {
    res2.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }
  }

The previous filter code allows the requests to propagate to the next filter or resource, only if the incoming request has the JavaEE user principal authorization. If the request is unauthorized, the filter sends the client to the error page, if defined. Notice how we recast the Servlet and response objects to HttpServletRequest and HttpServletResponse.

Obviously the Java EE web container will need to have security principals and realms defined externally to the web application in order for this filter to work.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.37.20