Interceptors, GSP Views, and Custom Tags

Harry · 13 Sep 2026 · 2 views

Part 1 - Interceptors

Interceptors run code before, after, or around controller actions - perfect for authentication checks, audit logging, or response headers.

class LoggingInterceptor {
    LoggingInterceptor() {
        matchAll()
    }

    boolean before() {
        log.info("Request to ${controllerName}/${actionName}")
        true   // continue processing
    }

    boolean after() { true }
    void afterView() { }
}

The flow is: before() runs, the action executes, after() runs, the view renders, then afterView() fires.

Part 2 - GSP Views

GSP is Grails' Groovy-based template engine - like JSP but far more expressive.

# in a controller
def index() {
    [users: User.list()]
}
<ul>
  <g:each in="${users}" var="u">
    <li>${u.username}</li>
  </g:each>
</ul>

Layouts and Templates

Layouts give every page a shared shell:

<!-- grails-app/views/layouts/main.gsp -->
<html><body><g:layoutBody/></body></html>

A page opts in with:

<meta name="layout" content="main"/>

Templates are reusable fragments:

<g:render template="userRow" model="[user: u]"/>

Forms, Errors, and Links

<g:form controller="user" action="save">
  <g:textField name="username"/>
  <g:submitButton name="Save"/>
</g:form>

<g:link controller="user" action="show" id="${user.id}">View</g:link>

<g:hasErrors bean="${user}">
  <g:eachError bean="${user}" var="err">${err.defaultMessage}<br/></g:eachError>
</g:hasErrors>

Escaping and Security

GSP escapes output by default. Escape user input and use raw() only when you control the content.

Part 3 - Custom Tag Libraries

Tag libraries encapsulate reusable UI logic and keep views clean:

class UiTagLib {
    static namespace = "ui"

    def button = { attrs, body ->
        def type = attrs.type ?: "button"
        out << "<button type='${type}'>${body()}</button>"
    }
}

Used in GSP as:

<ui:button type="submit">Save</ui:button>

Tag libraries access request, session, params, and grailsApplication, and can render templates or enforce role-based rendering.

Best Practices

  • Keep views simple and logic in services/taglibs.
  • Use tags over scriptlets.
  • Reuse layouts and templates.
  • Always escape user output.

Key Points

  • Interceptors wrap controller actions cleanly.
  • GSP combines Groovy with expressive tags.
  • Layouts and templates eliminate duplication.
  • Custom taglibs create DSL-like UI components.
Share this post:

Comments (0)

Please login or register to comment.