【问题标题】:Validation and validation errors in Service Layer服务层中的验证和验证错误
【发布时间】:2012-03-19 06:07:53
【问题描述】:

我从最新的 Java 开发中了解到,抛出 RuntimeException 并以面向方面的方式处理它是服务层错误处理的当前趋势。这意味着,如果出现任何问题,您只需抛出 RuntimeException 或者更好,让 Bean Validation 发挥作用。

优点是:你不会用try-catchif(entity.getName() == nil) 检查阻塞你的代码。一切都在后台检查,使您的代码更具可读性。

所以我想知道,这将如何在 Grails 中完成?当然,如果我使用.save(failOnError:true),我会得到一个不错的ValidationException。但这会导致一个非常令人不快的默认错误页面,根本不会提高 Web 应用程序的可用性。

我还需要将它放在控制器级别的try-catch 块中吗?假设EntityService 有一个方法,如下所示:

def toggleSomething(String entityId) = {
    if(!someOtherPrerequisite) {
        throw new EntityException("SomeOtherPrerequisite was not satisfied") // extends RuntimeException
    }

    Entity entity = Entity.get(entityId)
    entity.someProperty = somePropertyValue
    entity.save(failOnError:true) // throws a ValidationException
}

然后控制器会这样调用它:

def toggle = {
    try {
        entityService.toggleSomething(params.id)
    }
    catch(e) {
        flashHelper.error 'I'm sorry, something went wrong.'
    }
}

但是当 Grails 在很多方面都是新的学校时,这似乎是相当老派的。难道没有办法更好地处理RuntimeExceptions 而不用try-catch 阻塞代码吗?

【问题讨论】:

    标签: validation grails grails-2.0


    【解决方案1】:

    我遵循的模式是:

    1. 如果错误可以包含在 Grails 域中,则不要直接处理异常处理。如果您的服务方法主要处理您的 grails 域,那么当出现错误时,它们会在 domain.errors 集合中结束。在控制器中,只需检查这些错误(hasErrors())。因为无论如何都会在幕后引发 RuntimeException,所以您的事务被回滚,没有伤害,没有犯规。

    2. 如果您正在处理第三方库(可能是外部 Web 服务等),请不要害怕异常。仅仅因为 Grails (Groovy) 不需要您处理它们,它们仍然很适合拥有/使用。

    3. 有时以上都不适用,也许您的服务方法应该只返回一些关于某些逻辑结果的真或假标志。举个例子,例如:

    服务

        def toggleSomething(String entityId) = {
            if(!someOtherPrerequisite) {
                return false
            }
        }
    
            Entity entity = Entity.get(entityId)
            entity.someProperty = somePropertyValue
            entity.save() // throws a ValidationException
            return entity.hasErrors()
        }
    

    控制器

        def toggle = {
            if (!entityService.toggleSomething(params.id)) {
                flashHelper.error 'I'm sorry, something went wrong.'
            }
        }
    

    不幸的是,可能没有可靠的正确或错误方法来解决这个问题。所以期待与我不同的答案。

    【讨论】:

    • 谢谢。我阅读了更多文章并将其与您的代码示例相似,但我在服务中返回了有错误的实体。如果它完全有错误,只需将其作为布尔值返回是一个好主意,并且在许多情况下肯定就足够了。
    • 没错,我一直在等待更多输入,但在我看来,您是 SO 上唯一的 Grails 专家。 ;)
    猜你喜欢
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2013-08-07
    • 2010-11-01
    相关资源
    最近更新 更多