Fork me on GitHub

A filter can be any regular Route that doesn’t commit the response.

For example we can create an AuditFilter (a before filter) with this code:

// audit filter
ANY("/.*", routeContext -> {"Request for {} '{}'", routeContext.getRequestMethod(), routeContext.getRequestUri());;

In above snippet we added a before filter on all requests, this filter logs the request method and the request URI.
At the end of the filter we MUST call to jump to the next route/filter from the chain.

Note: If you want to add a filter for all routes you MUST use /.* and NOT /*:

Another before filter can be an AuthenticationFilter:

// authentication filter
GET("/contact.*", routeContext {
    if (routeContext.getSession("username") == null) {
    } else {;

In above snippet we protected all contact pages. If the current session doesn’t contain an attribute username then our filter redirects the request to the login page.

Now for a complicated scenario where we are getting a Database instance to be shared throughout a request-response cycle:

// before filter that create a database instance
ANY("/.*", routeContext -> {
    routeContext.setLocal("database", getDatabase());;

// insert data in database
POST("/{id}", routeContext -> {
    Database database = routeContext.getLocal("database");
    database.insert(something); // this line can throws an error

// after filter that release the database instance
ANY("/.*", routeContext -> {
    Database database = routeContextremoveLocal("database");

Please notice that we must mark the last filter with runAsFinally that are guaranteed to execute at the end of the Request-Response cycle despite exceptions within the chain.