Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails 3.0.11 AOP annotation to preprocess commandObjects before Controller methods

I am trying to retrieve the arguments of a grails controller method using an annotation and an Aspect that executes before the method. The aspect handler executes correctly but i cant access the argument(which implements grails.validation.Validateable) the list of arguments is empty.

experiment.aspect.validated

package experiment.aspect

import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

/**
 * Created by Vaggelis on 10/13/2016.
 */

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Validated {

}

experiment.aspect.ValidatedAspect

package experiment.aspect


import grails.validation.ValidationException
import org.aspectj.lang.JoinPoint

import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before


/**
 * Created by Vaggelis on 10/13/2016.
 */
@Aspect
class ValidatedAspect {

    @Before("@annotation(experiment.aspect.Validated)")
    public void preValidate(JoinPoint point) throws ValidationException{

        println "parameters  ${point.getArgs()}"


    }
}

conf.spring.resources

import experiment.aspect.ValidatedAspect

// Place your Spring DSL code here
beans = {
    validatedAspect(ValidatedAspect)
}

controllers.experiment.TestController

package experiment
import experiment.aspect.Validated
class TestController extends BaseController {
    static responseFormats = ['json']
    @Validated
    def login(LoginCommand loginCommand){
         println "Validated"
         ...
    }

}

experiment.LoginCommand

package experiment

/**
 * Created by Vaggelis on 9/14/2016.
 */
import grails.validation.Validateable


class LoginCommand implements Validateable {
//    String id
    String name
    static constraints = {
        name blank: false
    }
}

I get the following output, which means that the aspect handler method runs before the controller method but it does not get the arguments.

parameters []
Validated
like image 403
Evan Avatar asked Oct 30 '22 18:10

Evan


1 Answers

You're seeing no args because there aren't any.

To support databinding and to keep things simpler when the servlet decides which controller and method to call, an AST transform creates a new method with the same name and no args for all action methods that have any args. The zero-arg method is the one called initially by the servlet, and it has the logic added by the transform to make the data binding calls. After that's done it then it calls your parameterized method with param strings converted to int/long/boolean/command objects/etc.

The no-arg method will also be annotated with @grails.web.Action and the arg types specified in the commandObjects attribute. This will help find the other method, but it's actually simple because you'll get a compiler error if you declare overloaded public methods.

Having said all that, you probably don't want to use this approach even if it did work - there's already two existing standard ways to intercept controller action calls, Grails filters (now interceptors in 3.x) and servlet filters. Grails filters and interceptors make it trivial to inspect and optionally add, modify or delete request parameters, and if you return false from a 'before' call you will stop Grails from handling the request (e.g. because you rendered it yourself, or sent a redirect, etc.)

like image 133
Burt Beckwith Avatar answered Nov 09 '22 09:11

Burt Beckwith