TurboManage

David Chandler's Journal of Java Web and Mobile Development

  • David M. Chandler


    Web app developer since 1994 and Google Cloud Platform Instructor now residing in Colorado. Besides tech, I enjoy landscape photography and share my work at ColoradoPhoto.gallery.

  • Subscribe

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 223 other followers

  • Sleepless Nights…

    March 2010
    S M T W T F S
     123456
    78910111213
    14151617181920
    21222324252627
    28293031  
  • Blog Stats

    • 1,029,897 hits

Archive for March 11th, 2010

Server-side browser detection in a servlet filter

Posted by David Chandler on March 11, 2010

Second things first: if you need a polite, pretty, and usable way to help your users upgrade their browser, point them to WhatBrowser.org, created just for that purpose.

But first you have to find out what browser they’re currently running. I’ve implemented this as a servlet filter on my signup and login pages so as to inform users as early as possible if their browser is inadequate. The basic idea is to find some part of the User-Agent header that uniquely identifies each browser. “WebKit” and “Mozilla” are out because these appear in so many browsers. Fortunately, most browsers have their common name in the User-Agent string somewhere. By default, the filter allows Chrome, Firefox, Safari, Opera, and IE versions 6-8. You can configure the filter with your own list if desired.

package com.turbomanage.gwt.server.servlet;

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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.inject.Singleton;

@Singleton
public class BrowserFilter implements Filter
{
	// Be default, support all GWT-capable browsers
	// Assume any version recent enough except IE
	private static final String[] DEFAULT_BROWSERS =
	{ "Chrome", "Firefox", "Safari", "Opera", "MSIE 8", "MSIE 7", "MSIE 6" };

	// Filter param keys
	public static final String KEY_BROWSER_IDS = "browserIds";
	public static final String KEY_BAD_BROWSER_URL = "badBrowserUrl";

	// Configured params
	private String[] browserIds;
	private String badBrowserUrl;

	@Override
	public void init(FilterConfig cfg) throws ServletException
	{
		String ids = cfg.getInitParameter(KEY_BROWSER_IDS);
		this.browserIds = (ids != null)?ids.split(","):DEFAULT_BROWSERS;

		badBrowserUrl = cfg.getInitParameter(KEY_BAD_BROWSER_URL);
		if (badBrowserUrl == null)
		{
			throw new IllegalArgumentException("BrowserFilter requires param badBrowserUrl");
		}
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
		throws IOException, ServletException
	{
		String userAgent = ((HttpServletRequest) req).getHeader("User-Agent");
		for (String browser_id : browserIds)
		{
			if (userAgent.contains(browser_id))
			{
				chain.doFilter(req, resp);
				return;
			}
		}
		// Unsupported browser
		((HttpServletResponse) resp).sendRedirect(this.badBrowserUrl);
	}

	@Override
	public void destroy()
	{
		this.browserIds = null;
	}
}

I’m using Guice, so this is what my configuration looks like. Of course, you can also use standard web.xml configuration instead.

package com.roa.server.guice;

import java.util.HashMap;

import com.google.inject.Singleton;
import com.google.inject.servlet.ServletModule;
import com.turbomanage.gwt.server.servlet.BrowserFilter;

public class DispatchServletModule extends ServletModule
{
	@Override
	public void configureServlets()
	{
		HashMap<String, String> filterCfg = new HashMap<String,String>();
		filterCfg.put(BrowserFilter.KEY_BROWSER_IDS, "Chrome,Firefox,Safari,Opera,MSIE 8");
		filterCfg.put(BrowserFilter.KEY_BAD_BROWSER_URL, "/s/bb.html");
		filter("/roa/signup/signup.jsp", "/roa/app/login", "/roa/app/index.html").through(
			BrowserFilter.class, filterCfg);
		...
	}
}

You initialize the filter with one or two parameters. The badBrowserUrl param is required. The filter will redirect any unsupported browser to this location. You can optionally set your own comma-separated list of browser identification strings in the browserIds param.

For further research on browser server-side identification, check out http://www.zytrax.com/tech/web/browser_ids.htm.

Posted in GIN / Guice, Google Web Toolkit | 3 Comments »

 
%d bloggers like this: