{"id":41835,"date":"2016-11-11T15:44:34","date_gmt":"2016-11-11T10:14:34","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=41835"},"modified":"2016-12-19T15:04:04","modified_gmt":"2016-12-19T09:34:04","slug":"grails-3-migrating-from-filters-to-interceptors","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/grails-3-migrating-from-filters-to-interceptors\/","title":{"rendered":"Grails 3 &#8211; Migrating from Filters to Interceptors"},"content":{"rendered":"<p>Grails 3 comes with lots of new features and performance improvements, one\u00a0of them being\u00a0Interceptors which is a kind of a replacement for Filters from earlier versions of <a title=\"Grails Development\" href=\"http:\/\/www.tothenew.com\/grails-application-development\" target=\"_blank\">Grails<\/a>.<\/p>\n<p>Filters are used to apply logic across the\u00a0whole group of Controllers, URI, or to a particular action and are used in most of the\u00a0Grails projects.<\/p>\n<p>Though, you can still have filters in Grails 3 by adding the plugin and making few tweaks(footnote), but I would recommend moving to Interceptors as it offers a number of benefits over filters. One such benefit is including support for CompileStatic\u00a0which is critical from the performance perspective because an Interceptor is\u00a0executed for every request. Another advantage is flexible configurability. For example &#8211; an Interceptor may define a property by name which matches the configuration in\u00a0application.yml.<\/p>\n<p>So now, let see how we can create an Interceptor in Grails 3:<\/p>\n<p>[sourcecode language=&#8221;shell&#8221;]<br \/>\n    grails create-interceptor DemoInterceptor<br \/>\n[\/sourcecode]<\/p>\n<p>The above command\u00a0will create a groovy class in grails-app\/controller\/interceptorBlog\/DemoInterceptor.groovy.<\/p>\n<p>Similar to filters, interceptors contain code which will be applied to requests before and after calling controller actions. Following is a sample code of <em>DemoInterceptor<\/em>:<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\npackage interceptorBlog<\/p>\n<p>class DemoInterceptor {<\/p>\n<p>    boolean before() { true }<\/p>\n<p>    boolean after() { true }<\/p>\n<p>    void afterView() {<br \/>\n      \/\/ no-op<br \/>\n    }<br \/>\n}<\/p>\n<p>[\/sourcecode]<\/p>\n<ul>\n<li>By default, the interceptor will match the controller with the\u00a0same name such as &#8211; DemoInterceptor that will match every request with DemoController.<\/li>\n<li>If the\u00a0method before and after return true the processing continues, further processing of the\u00a0request is ignored.<\/li>\n<li>The afterView\u00a0method is executed after view rendering completes. If an exception occurs, the exception is available using the throwable property.<\/li>\n<\/ul>\n<p>Now, that we understand interceptors a little bit, let&#8217;s see how we can replace existing Filters with Interceptors.<\/p>\n<h3>Creating an Interceptor which should log every request<\/h3>\n<p><a title=\"Grails migration\" href=\"http:\/\/www.tothenew.com\/blog\/traits-provided-by-grails-3\/\" target=\"_blank\">Grails 3 takes advantage of traits<\/a>,\u00a0a powerful feature of Groovy. All Interceptors implements grails.artefact.Interceptor trait, which provides access to common properties and methods such as &#8211; grailsApplication, params, session, request, render redirect etc and match, matchAll methods which come\u00a0handy while we need to match requests based on patterns or all requests. So, following will be the code inside our Interceptor:<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\npackage interceptorBlog<\/p>\n<p>class LogInterceptor {<\/p>\n<p>    LogInterceptor() {<br \/>\n        matchAll()<br \/>\n    }<\/p>\n<p>    boolean before() {<br \/>\n        log.info(&quot;INCOMING REQUEST: ${params.toString()}&quot;)<br \/>\n        true<br \/>\n    }<\/p>\n<p>    boolean after() { true }<\/p>\n<p>    void afterView() {<br \/>\n        \/\/ no-op<br \/>\n    }<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p><strong>Note<\/strong>\u00a0that the default logger name for an interceptor is grails.app.controllers\u00a0so you also need to configure logging in\u00a0logback.groovy as:<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\n    logger(&quot;grails.app.controllers.interceptorBlog.LogInterceptor&quot;, INFO, [&#8216;STDOUT&#8217;], false)<br \/>\n[\/sourcecode]<\/p>\n<h3>Create an Interceptor to authenticate my REST call for a valid token<\/h3>\n<p>Here we need to match every request except for AuthController against a valid token. If a\u00a0token is valid then continues processing, otherwise respond 401. So, the\u00a0following is the code for interceptor.<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\npackage demo<\/p>\n<p>import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED<\/p>\n<p>class RestInterceptor {<\/p>\n<p>    RestInterceptor() {<br \/>\n        matchAll()<br \/>\n          .excludes(controller: &#8216;auth&#8217;)<br \/>\n    }<\/p>\n<p>    boolean before() {<br \/>\n        String token = session.token ?: request.getHeader(&#8216;token&#8217;)<br \/>\n        if(!token) { \/\/ Please note you could also have your own custom validation logic here<br \/>\n            response.status = SC_UNAUTHORIZED<br \/>\n            return false<br \/>\n        }<br \/>\n        true<br \/>\n    }<\/p>\n<p>    boolean after() { true }<\/p>\n<p>    void afterView() {<br \/>\n        \/\/ no-op<br \/>\n    }<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<ul>\n<li>The matchAll\u00a0method defined in <a title=\"Interceptor API\" href=\"http:\/\/docs.grails.org\/3.2.2\/api\/grails\/artefact\/Interceptor.html\">Interceptor API<\/a>, returns the <a title=\"Matcher\" href=\"http:\/\/docs.grails.org\/3.2.2\/api\/grails\/interceptors\/Matcher.html\">Matcher<\/a> instance which can be used to configure how Interceptor matches the request.<\/li>\n<\/ul>\n<h3>I used to authenticate on beforeInterceptor method on older Grails versions, How to do it in Grails 3?.<\/h3>\n<p>As you already know that Before and after interceptors were removed. So all beforeInterceptor and afterInterceptor\u00a0need to be replaced by Stand alone interceptors. For example, the following would not work anymore:<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\npackage interceptorBlog<\/p>\n<p>class UserController {<br \/>\n    def beforeInterceptor = [action: this.&amp;auth, except: &#8216;login&#8217;]<\/p>\n<p>    private auth() {<br \/>\n        if (!session.user) {<br \/>\n            redirect(action: &#8216;login&#8217;)<br \/>\n            return false<br \/>\n        }<br \/>\n    }<br \/>\n    def login() {<br \/>\n        \/\/ display login page<br \/>\n    }<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p>Similar functionality in Grails 3 can be achieved by creating a new Interceptor named <em>UserInterceptor.groovy<\/em> as follows:<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\npackage interceptorblog<\/p>\n<p>class UserInterceptor {<\/p>\n<p>    UserInterceptor() {<br \/>\n        match(controller: &quot;user&quot;, action: &quot;*&quot;)<br \/>\n                .except(action: &quot;login&quot;)<br \/>\n    }<\/p>\n<p>    boolean before() {<br \/>\n        if (!session.user) {<br \/>\n            redirect(action: &#8216;login&#8217;)<br \/>\n            return false<br \/>\n        }<br \/>\n        true<br \/>\n    }<\/p>\n<p>    boolean after() { true }<\/p>\n<p>    void afterView() {<br \/>\n        \/\/ no-op<br \/>\n    }<br \/>\n}<br \/>\n[\/sourcecode]<\/p>\n<p>To read more about Interceptors please go to Grails Documentation.<\/p>\n<p>If you still feel the need to continue with Filters in Grails 3, there is separate plugin available and you can use it by simply adding following as dependency in your\u00a0build.gradle.<\/p>\n<p>[sourcecode language=&#8221;groovy&#8221;]<br \/>\n  compile &#8216;org.grails:grails-plugin-filters:3.0.12&#8217;<br \/>\n[\/sourcecode]<\/p>\n<p><strong>Please note<\/strong> that you need to move filters out from grails-app\/conf directory to any other source directory such as grails-app\/controllers\u00a0folder as grails-app\/conf\u00a0is not considered as source directory anymore.<\/p>\n<p>Hope it helps.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Grails 3 comes with lots of new features and performance improvements, one\u00a0of them being\u00a0Interceptors which is a kind of a replacement for Filters from earlier versions of Grails. Filters are used to apply logic across the\u00a0whole group of Controllers, URI, or to a particular action and are used in most of the\u00a0Grails projects. Though, you [&hellip;]<\/p>\n","protected":false},"author":57,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":68},"categories":[7,1],"tags":[4840,3219,4180,4183,4182,4181,1855],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/41835"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/57"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=41835"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/41835\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=41835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=41835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=41835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}