spring - Grails 3.0.11 AOP 注释在 Controller 方法之前预处理命令对象

标签 spring grails annotations aop

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

实验.方面.验证

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 {

}

实验.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"
         ...
    }

}

实验.登录命令
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
    }
}

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

最佳答案

你没有看到任何参数,因为没有。

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

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

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

关于spring - Grails 3.0.11 AOP 注释在 Controller 方法之前预处理命令对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40027866/

相关文章:

grails - 无法在STS 4.1.2上安装GGTS

java - 注解处理器,获取方法参数的修饰符

java - 查找被注释处理覆盖的方法

spring - 对于Spring自动检测,组件和服务有什么区别?

java - 在方法中使用 spring 注解启动调度程序

java - Spring MVC - <form :errors> empty, BindingResult 包含错误

java - Spring Boot 中的自定义 PropertySource 会阻止某些属性加载

Grails 自定义验证器,获取对字段名称的引用

java - Spring Security 和 OAuth2 生成具有自定义授权类型的 token

oracle - Grails中与众不同,oracle和CLOB错误