Tuesday, 14 July 2009

Servlet Filter

FilterChain is an object provided by the servlet containner to the developer. Filters can use FilterChain to invoke the next filter, or invoking the resources as at the end of filter chain.

Redirecting a request

Another use for filters is to restrict access to resources - if a filter doesn't call FilterChain.doFilter(), the resource won't be loaded. Simply returning would send an empty document to the browser, so it's better to redirect or forward the request to a different resource. As with a servlet, there are two ways to do this. HttpServletReponse.sendRedirect() actually sends a response to the browser giving it a URL to fetch instead of the original one, which may be on a different server. The other option is to use a RequestDispatcher to load a different resource on the server instead of the resource which would have been loaded, transparently to the browser.

Unfortunately the Tomcat project doesn't provide any useful examples for this, so I'm reduced to writing my own code. SecureFilter checks the current session to see whether there is a User object; if not, it forwards the request to a login form. While hardly a robust component, you can see how a more useful system could be implemented.

public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException
{
boolean authorized = false;
if (request instanceof HttpServletRequest) {
HttpSession session = ((HttpServletRequest)request).getSession(false);
if (session != null) {
User user = (User) session.getAttribute("user");
if (user != null)
authorized = true;
}
}

if (authorized) {
chain.doFilter(request, response);
return;
} else if (filterConfig != null) {
String login_page = filterConfig.getInitParameter("login_page");
if (login_page != null && !"".equals(login_page)) {
filterConfig.getServletContext().getRequestDispatcher(login_page).
forward(request, response);
return;
}
}

throw new ServletException
("Unauthorized access, unable to forward to login page");

}

Threading issues

Can Jackson Deserialize Java Time ZonedDateTime

Yes, but must include JSR310. Thus ZonedDateTime can be deserialized directly from JSON response to POJO field. <dependency> <g...