【问题标题】:Return specific HTTP Error Code from Grails Command Object validation从 Grails 命令对象验证返回特定的 HTTP 错误代码
【发布时间】:2016-09-20 12:55:24
【问题描述】:

给定一个 REST 端点的设置,例如保存一个用户,是否可以使用命令对象的 validate() 来获取特定的 HTTP 错误代码,这些代码可以返回给控制器以处理响应?

我想避免控制器操作必须处理大量 if 块、检查特定错误消息并进行查找/将其转换为 HTTP 错误代码的情况。

例如,如果在数据库中找不到匹配的用户,我希望自定义验证器以某种方式告诉控制器返回 404。

以下不是我尝试过的。相反,它只是我想用于验证 REST 参数的理想结构的概念证明。也许这是完全错误的,或者有更好的方法。如果有,那也很受欢迎。

例如:

用户.groovy

...
class User {
    String username

    static constraints = {
        username unique:true
    }
}

UserController.groovy

...
class UserController extends RestfulController {
    def update(UserCommand userCmd) {
        /*
         * Not actually working code, but proof of concept of what 
         * I'm trying to achieve
         */
        render status: userCmd.validate()
    }

    class UserCommand {
        Long id
        String username

        static constraints = {
            importFrom User

            /* 
             * I also get that you can't return Error codes via the 
             * custom validator, but also just to illustrate what I'm
             * trying to achieve
             */
            id validator: { 
                User user = User.get(id)
                if(user == null) {
                    return 404
                }
            }
        }
    }
}

【问题讨论】:

    标签: rest validation grails


    【解决方案1】:

    所以你的例子没有多大意义。如果您正在保存用户并且找不到它,那很好,不是吗?如果您要更新用户,您可能会在控制器中调用update() 操作。

    也就是说,虽然这似乎是个好主意,但由于它行不通,我建议更像以下内容:

    class UserController {
    
        def edit() {
            withUser { user ->
                [user:user]
            }
        }
    
        private def withUser(id="id", Closure c) {
            def user = User.get(params[id])
            if(user) {
                c.call user
            } else {
                flash.message = "The user was not found."
                response.sendError 404
            }
        }
    }
    

    您可以调整它以处理您的命令对象,但我认为这给出了更多DRY 的一般概念。

    【讨论】:

    • 您能否解释一下或指出一些文档来解释您的id="id" 方法中的withUser 参数?我不知道我害怕什么。
    • 这只是一个可以覆盖的变量。因此,如果您想通过不同的参数查找对象,请将其作为 id 而不是默认的“id”传递。
    【解决方案2】:

    也许您应该尝试返回 404,但随后您解析并执行其他操作的实际错误

    一开始你不会有大量的错误代码(that will make proper sense and actually valid)

    if (userCmd.validate()) {
      def error=userCmd.errors.allErrors.collect{g.message(error : it)}
      render status:404,text: error
      return
    }
    //otherwise 
     render status:201, text: 'something'
    

    你也可以这样做

    response.status=404
    render "Some content"
    

    【讨论】:

      猜你喜欢
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多