Grails 3.3 with Servlet Filter

I had a scenario (I don’t really want to get into it) where I needed to implement a proper servlet filter which would run before the Grails dispatcher got involved in the request. The Grails documentation says it can be done, but the instructions are ridiculously vague, and seem more centered on plugins rather than just a webapp.

I finally managed to work it out, and I wanted to show the source code involved for posterity, and anyone else who might stumble upon this solution.

First off, create your filter in /src/main/java/myPackage:

package myPackage;

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

/**
 * @author Nathan Crause <[email protected]>
 */
@WebFilter(filterName = "testFilter", urlPatterns = {"/*"})
public class TestFilter implements Filter {

	private FilterConfig filterConfig;

	public TestFilter() {
	}

	/**
	 * @param request The servlet request we are processing
	 * @param response The servlet response we are creating
	 * @param chain The filter chain we are processing
	 *
	 * @exception IOException if an input/output error occurs
	 * @exception ServletException if a servlet error occurs
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		for (int i = 0; i < 100; ++i) {
			for (int c = 0; c < 80; ++c) {
				System.out.print("-");
			}
			System.out.println();
		}

		chain.doFilter(request, response);
	}

	/**
	 * Destroy method for this filter
	 */
	@Override
	public void destroy() {		
	}

	/**
	 * Init method for this filter
	 * @param filterConfig
	 */
	@Override
	public void init(FilterConfig filterConfig) {		
		this.filterConfig = filterConfig;
	}

}

Now the really poorly documented part – where the hell do you tell Grails to load the damned thing? Turns out you just use /grails-app/conf/spring/resources.groovy:

import org.springframework.core.Ordered
import org.springframework.boot.web.servlet.FilterRegistrationBean
import myPackage.TestFilter

beans = {
	testFilter(FilterRegistrationBean) {
		filter = bean(TestFilter)
		urlPatterns = ['/*']
		// we want all other Grails filters to have loaded first
		order = Ordered.LOWEST_PRECEDENCE
	}
}

Now, I originally opted for using pure Java for the speed, but it did expose the problem that none of my domain classes were accessible, which I did require. So, I re-implemented the filter as a Groovy class in the /grails-app/controllers/myPackage directory.

It’s also worth noting that you will be required to create a new hibernate session in order to perform queries.

package myPackage

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

/**
 * @author Nathan Crause <[email protected]>
 */
class TestFilter implements Filter {
	
	FilterConfig filterConfig
	
	void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
		for (int i = 0; i < 10; ++i) {
			println("-" * 80)
		}

		Account.withNewSession {
			println(Account.last().inspect())
		}

		chain.doFilter(request, response)
	}
	
	void destroy() {		
	}
	
	void init(FilterConfig filterConfig) {		
		this.filterConfig = filterConfig
	}
	
}

Project: Kalliope

Last year, I set myself the task of trying to actually produce a bunch of smaller web projects for s few reasons:

  • To learn some new frameworks
  • To illustrate my ability to learn there different frameworks
  • To showcase my skills in development in general

To that end, I thought I’d explain each project here in my blog, and the motivation behind each.

First up is Kalliope – https://kalliope.hostnucleus.ca

This is a “font server” with two primary end-goals – be able to arbitrarily upload a true type font, and have it produce web downloadable fonts, or to actively serve unlicensed fonts (in the same vein as Google Fonts).

The latter end-goal (as detailed above) was actually the primary goal on project inception – I wanted to have the ability to use a variety of fonts, but I didn’t want Google snooping the traffic on my sites (e.g. cookies, etc.). You can think of it as a replace for Google Fonts, really.

The other end-goal came about when the place where I worked had a client who had purchased some proprietary font, and wanted it used on their website. I didn’t want this font directly in the font server itself (as it requires a license), but all the leg-work had already been done to perform the conversion.

Interestingly enough, the original work on this was actually done for a completely different project – I had implemented a lot of the code within a project for generating print materials using SVGs. Since the SVGs needed to be displayable in all browsers, as well as the final PDF, I decided to use “FontForge” to do all the heavy lifting. It was only years later when developing a website where it occurred to me to break out the functionality into a separate web service.

It’s also a good project to learn and showcase the Grails framework.

Grails/Spring service autowiring

While working on a Grails project, I came across 2 interesting things:

  1. autowiring for domain classes doesn’t work, even if you follow all the instructions on how to enable it (either globally, or in the domain class definition itself)
  2. autowiring on abstract service classes doesn’t work (so if you’re implementing a data service with some custom functionality, your services won’t get autowired)

I’ve been able to fix both of these issues using a very simple utility class:

import grails.util.Holders

/**
 * Since Grails doesn't seem capable of autowiring into abstract classes, this
 * causes a bit of an issue when creating data services which do more than
 * just get/save.
 * 
 * All those context beans are available, so we just need to fudge the idea of
 * autowiring, and this class helps by providing a quick reference to the
 * singe long line required to get those Spring beans.
 * 
 * This also helps with domain classes, which have autowiring disabled, and
 * despite all the documentation saying the contrary, into which you cannot
 * autowire.
 * 
 * That said, this might prove to be a faster solution for use within domain
 * classes anyway since we don't have to worry about autowiring happening on
 * every object instantiation, but rather we just have a reference to the
 * singular instance with in the main context.
 */
class Beans {
	
	static def get(String name) {
		Holders.grailsApplication.mainContext.getBean(name)
	}
	
	static def $static_propertyMissing(String name) {
		get(name)
	}
	
}

Now, instead of setting up a service like this:

def myService

You instead define a getter method like this:

def getMyService() {
    Beans.myService
}

You can then use “myService” as you would’ve expected to under normal autowiring circumstances.