【问题标题】:How to enforce Grails command objects have been validated?如何强制执行 Grails 命令对象已经过验证?
【发布时间】:2013-09-16 21:15:14
【问题描述】:

我们对 Grails 控制器和命令对象使用以下通用模式

SomeController {
    def someAction() {
        SomeCommandObject co = SomeCommandObject.valueOf(params)

        if(!co.validate()) {
            // return bad request
        }

        someService.doWork(co)
        // return ok
}

SomeService {
    def doWork(SomeCommandObject co) {
        notTrue(!co.hasErrors(), 'cant have errors') // Commons validation

        // do actual work
    }
}

显然,如果 co.validate() 没有被调用,.hasErrors() 将总是返回 false。有没有更好的方法来强制在应用层之间传递命令对象之前调用 .validate() ?我们不想传递无效的命令对象,但我们也不想强制每个新方法重新验证命令对象。

注意:我们没有使用默认的控制器/命令对象创建模式,因为我们需要做一些自定义参数映射检查,我们使用静态 valueOf 方法来创建命令对象。也欢迎改变这种做法的答案。

编辑:关于我们为什么不使用“默认”控制器/命令对象创建的更多信息。具体为什么我们不这样做..

def someAction(SomeCommandObject co) {
}

我们要求禁止随机查询参数,例如。端点/对象?颜色=蓝色。为此,我们需要访问命令对象中的参数映射,以验证它不包含任何“意外”参数键。据我了解,默认方式只会在名为 color 的 CO 上创建一个成员,我看不出如何防止任意成员使用自定义验证器。我很乐意接受这样做的建议,从而允许我们使用这种默认方式。

【问题讨论】:

    标签: validation grails command-objects


    【解决方案1】:

    是的;您可以做的是将命令对象作为参数传递给控制器​​,然后该命令将始终自动验证。

    另外,你可以做一个过滤器或类似的东西,这样你就不必每次都检查 hasErrors() ,而是以相同的方式处理所有情况(例如,通过抛出错误,或返回特定响应)。

    在我们创建的应用程序中,我们有类似的东西:

    withValidCommand(cmd) {
         // do work
    }
    

    效果很好。但也许你可以想出更优雅的东西。

    【讨论】:

    • 这很有趣,我没想到过滤器。我会看看我能想出什么。
    【解决方案2】:

    你应该这样做:

    def someAction(SomeCommandObject co) {
        if (!co.hasErrors()) {
           someService.doWork(co)
        }
    }
    

    通过将 SomeCommandObject 作为参数传入 grails 将自动从 params 填充它并进行验证。无需手动操作。

    【讨论】:

    • 我在问题中添加了更多信息,解释了为什么我们不能只使用这种默认方式。如果您对如何实现我们的目标有任何建议,请。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多