如何覆盖Grails域类中的“map”构造函数?

时间:2011-09-13 10:35:46

标签: grails groovy gorm

我需要在创建域类的新实例时执行一些初始化。

class ActivationToken {
    String foo
    String bar
}

当我这样做时,我希望通过ActivationToken中的代码初始化bar:

def tok = new ActivationToken(foo:'a')

我无法看到如何“覆盖”'构造函数'来实现这一点。我知道在这种情况下我可以添加一个普通的构造函数,但这只是一个简单的例子。

2 个答案:

答案 0 :(得分:18)

地图构造函数来自Groovy - 在这种情况下不是Grails。我做了一些实验,这就是我提出的:

class Foo {
    String name = "bob"
    int num = 0

    public Foo() {
        this([:])
    }

    public Foo(Map map) {
        map?.each { k, v -> this[k] = v }
        name = name.toUpperCase()
    }

    public String toString() {
        "$name=$num"
    }
}

assert 'BOB=0' == new Foo().toString()
assert 'JOE=32' == new Foo(name:"joe", num: 32).toString()

基本上,如果你需要在构造之后处理属性,你似乎必须手动覆盖构造函数。

或者,您可以覆盖单个setter,这通常更干净,更安全:

class Foo {
    String name = "bob"
    int num = 0

    public void setName(n) {   
        name = n.toUpperCase()
    }

    public String toString() {
        "$name=$num"
    }
}

assert 'bob=0' == new Foo().toString()
assert 'JOE=32' == new Foo(name:"joe", num: 32).toString()

请注意,未处理默认值,但在大多数情况下应该没问题。

答案 1 :(得分:1)

上述解决方案也适用于从Web请求中的参数初始化对象的情况,例如,您希望忽略无关值,捕获Missing属性异常。

public Foo(Map map) {
    try {
        map?.each { k, v -> this[k] = v }
    }
    catch(Exception e){
    }
}