Search code examples
grailsgrails-2.0

What is the right way to detect if a request is a "forward()" from another controller action?


I have a couple of "before" type filters, which I would like to trigger only when a real, non-forwarded request arrives at my server. And not, when I sometimes am forwarding a request to another controller/action for further processing.

My questions if if there is a simple way to detect this particular kind of requests caused by a "forward()" call?

Alternatively, I am considering to parse the request url and check if controller and action match with the current controller/action, but I am not sure if this will work - and it sure is quite an ugly way to handle this issue...

From within my controller action I have tried to see if there were any useful attributes for this purpose on the request object, but could not find any, except from "javax.servlet.forward.request_uri" and "org.codehaus.groovy.grails.CONTROLLER_NAME_ATTRIBUTE" +"org.codehaus.groovy.grails.ACTION_NAME_ATTRIBUTE". However, it seems like comparing these values with each other will not work if the request uri originates from a UrlMapping,(in which case it might not match with the controller/action)


Solution

  • You can determine if a request was forwarded by looking up the servlet attribute org.grails.FORWARD_CALLED:

    request.getAttribute('org.grails.FORWARD_CALLED')
    

    Minimal example (in Grails 3.3.9, though same attribute in 2.5.x):

    def index() {
        forward action: 'fwd'
    }
    
    def fwd() {
        if (request.getAttribute('org.grails.FORWARD_CALLED')) {
            render 'was called by forward'
        } else {
            render 'called directly'
        }
    }
    

    Calling the endpoints:

    $ curl localhost:8080/foo/index
    was called by forward
    $ curl localhost:8080/foo/fwd
    called directly