Grails 3.0.11 AOP注释在Controller方法之前预处理commandObjects

Eva*_*van 5 grails aop spring annotations

我试图使用注释和在方法之前执行的Aspect检索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 {

}
Run Code Online (Sandbox Code Playgroud)

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()}"


    }
}
Run Code Online (Sandbox Code Playgroud)

conf.spring.resources

import experiment.aspect.ValidatedAspect

// Place your Spring DSL code here
beans = {
    validatedAspect(ValidatedAspect)
}
Run Code Online (Sandbox Code Playgroud)

controllers.experiment.TestController

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

}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

parameters []
Validated
Run Code Online (Sandbox Code Playgroud)

Bur*_*ith 2

你看不到参数,因为根本就没有参数。

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

无参数方法也将被注释,@grails.web.Action并且参数类型在commandObjects进行注释。这将有助于找到其他方法,但实际上很简单,因为如果声明重载的公共方法,您将收到编译器错误。

说了这么多,您可能不想使用这种方法,即使它确实有效 - 已经有两种现有的标准方法来拦截控制器操作调用:Grails 过滤器(现在是 3.x 中的拦截器)和 servlet 过滤器。Grails 过滤器和拦截器使得检查和有选择地添加、修改或删除请求参数变得很简单,如果您从“之前”调用返回 false,您将阻止 Grails 处理该请求(例如,因为您自己渲染了它,或者发送了重定向) , ETC。)