Building the Filter
We've now constructed our database of browser settings and can search it, returning a BrowserInfo
object encapsulating everything we know about a particular browser. The last step is to make this
functionality available to our web applications. As we discussed earlier, we do this with a filter that
intercepts requests and parses the USER-AGENT request header, exposing a BrowserInfo object as an
attribute of either the request or the session.
Defining Constants
First we need to define some constants that the filter (and the custom tags we will build shortly) will
need: the default name of the request or session attribute, and the default location of the
browscap.ini file. We will allow both to be overridden by specifying initialization parameters for
the filter:
package com.wrox.browser;
public class Constants {
public final static String BROWSER_INFO = "com.wrox.browser";
public final static String DEFAULT_BROWSCAP_LOCATION =
"/WEB-INF/browscap.ini";
}
The BrowserFilter Class
The filter itself is the next component to be written. Three initialization parameters can be specified:
| Parameter | Meaning | Defaut Value |
| scope | The scope under which the BrowserInfo object should be stored: request or session | session |
| name | The name of the request or session attribute containing the BrowserInfo object | com.wrox.browser |
| browscap | The location within the web application of the browscap.ini file | /WEB-INF/browscap.ini |
BrowserFilter starts simply enough: it holds instance variables that will contain the scope and name
information from the initialization parameters, along with our BrowserDatabase instance. These are
set in the init() method. Here we also use the ServletContext method getResourceAsStream()
to open an InputStream on the browscap.ini file, which we then pass to the
BrowserDatabase constructor:
package com.wrox.browser;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class BrowserFilter implements Filter {
We need a number of instance variables. Here is our FilterConfig instance:
private FilterConfig filterConfig = null;
A boolean to remember whether we want to store the BrowserInfo bean under request scope, rather
than the default session scope:
private boolean requestScope = false;
Our BrowserDatabase instance:
private BrowserDatabase data = null;
The name to use when stashing the bean away in request or session:
private String name = null;
The init() method initializes the BrowserFilter. If the browser information database could not be
opened or read it will throw a ServletException:
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
After storing away the FilterConfig we need to check the values of the various
initialization parameters:
String sessionParam =
filterConfig.getInitParameter("scope");
if ((sessionParam != null) &&
(sessionParam.equalsIgnoreCase("request"))) {
requestScope = true;
}
String browscapLocation =
filterConfig.getInitParameter("browscap");
if (browscapLocation == null) {
browscapLocation = Constants.DEFAULT_BROWSCAP_LOCATION;
}
name = filterConfig.getInitParameter("name");
if (name == null) {
name = Constants.BROWSER_INFO;
}
The location of the browscap.ini file was as a path within the web application, so we use the
ServletContext method getResourceAsStream() to open an InputStream to it:
try {
InputStream in = filterConfig.getServletContext()
.getResourceAsStream(browscapLocation);
if (in == null) {
throw new ServletException
("Could not open browser settings file " +
browscapLocation);
}
data = new BrowserDatabase(in);
} catch (BrowserException e) {
throw new ServletException(
"Browser filter initialization failed", e);
}
}
No special work is required in the destroy() method to take the filter out of service:
public void destroy() {
this.filterConfig = null;
}
As with all filters, the real work happens in doFilter(). Before invoking the next filter in the chain we
look up the USER-AGENT request header and ask the database for the best-match BrowserInfo to
represent it. This is then stored as a request or session attribute, depending on the filter configuration.
Note that if we are storing it in the session we only need to do the database lookup once, since we can
assume that all requests in the same session will be coming from the same actual browser instance:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if (filterConfig == null) {
return;
}
If the BrowserInfo bean is to be stored in request scope, then we just obtain the USER-AGENT header
and ask the BrowserDatabase to look it up:
if (requestScope) {
String userAgent = httpRequest.getHeader("USER-AGENT");
BrowserInfo info = data.lookup(userAgent);
request.setAttribute(name, info);
If, on the other hand, it is to be stored in the session, we first check whether there is already a session
attribute of the correct name. If there is, then this user session has already had its browser detected and
there is no need to repeat the operation:
} else {
HttpSession session = httpRequest.getSession();
if (session.getAttribute(name) == null) {
String userAgent = httpRequest.getHeader("USER-AGENT");
BrowserInfo info = data.lookup(userAgent);
session.setAttribute(name, info);
}
}
chain.doFilter(request, response);
}
}
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|