在Grails中,你可以声明一个这样的控制器动作:
def create(Integer foo, Integer bar) {
}
如果您的HTTP请求包含名为foo
和bar
的参数,其值可以转换为Integer
,则会为参数分配这些值。我想知道Grails如何做到这一点,因为我的理解是在JVM字节码级别,方法的形式参数名称不可用。这是巫术,还是我误解了什么?
答案 0 :(得分:3)
基本上会发生的是,有一个AST变换添加了一个没有args和相同名称的新方法。这个新方法在其中具有逻辑,可以根据“真实”方法的声明类型进行数据绑定,然后调用您的方法。这就是为什么类型是必需的(否则无法进行转换)以及为什么你不能有方法重载。
无法重载方法很容易解决。说你想要一个动作
def foo(String bar)
和另一个
def foo(String bar, Integer wahoo)
在这种情况下,只需保留第二种方法并检查wahoo
是否为空。
使用对象参数类型而不是基元也很重要。如果您使用int
/ long
/ boolean
/等。并且没有提供参数,你会得到一个NPE(因为零对于数字来说不是null的可接受转换,并且对于布尔值来说都是假的。)
如果使用JD-GUI或其他反编译器对类进行反编译,你可以对正在发生的事情有所了解。
答案 1 :(得分:1)
Grails控制器是Groovy类的事实有很大帮助。通过查看source code for controllers,您可以看到它大量使用AST转换,特别是MethodNode。因此,在它成为字节码之前,“巫术”就完成了。 :)