Gretty version 1.1.7+ implements new feature: redirect filter, driven by groovy DSL. You can configure and use the redirect filter within any web-application, even if you deploy web-application as a WAR file to arbitrary servlet container (without Gretty).

Setup

  • Insert into "WEB-INF/web.xml" of your web-app:

<filter>
  <filter-name>RedirectFilter</filter-name>
  <filter-class>org.akhikhl.gretty.RedirectFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>RedirectFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>
  • Create file "WEB-INF/filter.groovy", insert code:

// here we forward context root path to "index.html"
filter relPath: '/', {
  forward 'index.html'
}

// here we redirect old path to a new path
filter relPath: '/old/path', {
  redirect contextPath + '/new/path'
}

// here we convert path parameter to query parameter
filter relPath: ~'/path/(.*)', { matches ->
  redirect new URIBuilder(requestURI).setPath(contextPath + '/anotherPath').setQuery(matches.relPath[0][1])
}

// here we redirect all HTTP traffic to HTTPS scheme and port
filter scheme: 'http', {
  redirect new URIBuilder(requestURI).setScheme('https').setPort(httpsPort)
}
Tip
you can (but you don’t have to) add dependency compile 'org.gretty:gretty-filter:$grettyVersion' to your project - this library implements redirect filter. Even if you don’t add it explicitly, Gretty will do it for you automatically, as soon as it discovers redirect filter in "web.xml".

Configuration DSL

Redirect filter supports the following groovy-based DSL for "filter.groovy":

/**
 * Adds new filter to filter chain.
 * Must be called in the top scope of "filter.groovy" script.
 * options - contains one or more filter criteria.
 * closure - represents filter handler, which is invoked only when all criteria are fulfilled.
 */

void filter(Map options, Closure closure)

/**
 * Redirects current HTTP request to the specified destination.
 * Must be called only within closure of filter function.
 * destination - can be URI, URIBuilder or String.
 */
void redirect(destination)

/**
 * Forwards current HTTP request to the specified destination.
 * Must be called only within closure of filter function.
 * destination - can be URI, URIBuilder or String.
 */
void forward(destination)

"options" represents filter criteria, that are implicitly combined with AND operator. For example, if you put the following into options:

filter relPath: '/path', scheme: 'http', {
  // ...
}

then program will check for relative path being equal to '/path' AND for scheme being equal to 'http'. Only when both comparisons are successful, then the closure will be called.

"options" supports two types of values: strings and regular expressions. Strings are compared as they are, while regular expressions are matched via =~ operator. The result of match is passed as map parameter to the closure. Example:

filter relPath: ~'/path/(*.)', query: ~'x=(.*)', { matches ->
  // if we get here, then matches.relPath[0][1] will contain first capture group for relPath regex,
  // while matches.query[0][1] will contain first capture group for query regex.
}

Redirect filter recognizes the following keys within "options":

key type meaning

httpPort

Integer

port configured for (unencrypted) HTTP connections within servlet container config

httpsPort

Integer

port configured for HTTPS connections within servlet container config

contextPath

String

context path of the given web-app (where "filter.groovy" is located)

authority

String

authority of request URI

fragment

String

fragment of request URI

host

String

host of request URI

path

String

path of request URI

port

String

port of request URI

query

String

query of request URI

scheme

String

scheme of request URI

userInfo

String

userInfo of request URI

relPath

String

path of the current HTTP request, relative to the current context path. For example, if context path is "/myWebApp" and request path is "/myWebApp/hello", then relPath is "/hello".

Redirect filter provides the following variables to filter closure:

key type meaning

requestURI

URI

the complete URI of the current HTTP request

request

HttpServletRequest

the request object

response

HttpServletResponse

the response object

webappDir

java.io.File

the directory of the current web-app, as returned by ServletContext().getRealPath('')

log

org.slf4j.Logger

Logger interface. Note that Gretty redirect filter does not depend on particular implementation of slf4j logger. It only depends on slf4j-api, so it’s up to you to initialize/configure slf4j properly.

httpPort

Integer

port configured within servlet container for (unencrypted) HTTP connections

httpsPort

Integer

port configured within servlet container for HTTPS connections

contextPath

String

context path of the current web-app

authority

String

authority of request URI

fragment

String

fragment of request URI

host

String

host of request URI

path

String

path of request URI

port

String

port of request URI

query

String

query of request URI

scheme

String

scheme of request URI

userInfo

String

userInfo of request URI

relPath

String

path of the current HTTP request, relative to the current context path. For example, if context path is "/myWebApp" and request path is "/myWebApp/hello", then relPath is "/hello".

Redirect filter automatically imports groovyx.net.http.URIBuilder class into "filter.groovy", so that you can instantiate it with a simple call new URIBuilder(uri).

You can import arbitrary java classes into "filter.groovy" with usual "import" instruction. Don’t forget to add corresponding dependencies within your "build.gradle" script.