Grails 3.0.11 AOP 注释在控制器方法之前预处理命令对象

Grails 3.0.11 AOP annotation to preprocess commandObjects before Controller methods

我正在尝试使用注释和在该方法之前执行的方面来检索 grails 控制器方法的参数。 方面处理程序正确执行但我无法访问参数(实现 grails.validation.Validateable)参数列表为空。

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
    }
}

我得到以下输出,这意味着方面处理程序方法在控制器方法之前运行,但它没有获取参数。

parameters []
Validated

您没有看到任何参数,因为根本没有。

为了支持数据绑定并在 servlet 决定调用哪个控制器和方法时使事情变得更简单,AST 转换为所有具有任何参数的操作方法创建一个具有相同名称且没有参数的新方法。零参数方法是最初由 servlet 调用的方法,它具有转换添加的逻辑以进行数据绑定调用。完成之后,它会调用您的参数化方法,并将参数字符串转换为 int/long/boolean/command objects/etc.

无参数方法也将使用 @grails.web.ActioncommandObjects 属性中指定的参数类型进行注释。这将有助于找到其他方法,但它实际上很简单,因为如果您声明重载的 public 方法,则会出现编译器错误。

话虽如此,您可能不想使用这种方法,即使它确实有效 - 已经有两种现有的标准方法来拦截控制器操作调用,Grails 过滤器(现在是 3.x 中的拦截器)和 servlet 过滤器。 Grails 过滤器和拦截器使得检查和可选地添加、修改或删除请求参数变得微不足道,如果你从 'before' 调用中 return false 你将停止 Grails 处理请求(例如,因为你渲染了它自己,或发送重定向等)