2016-09-20 57 views
0

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

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

例如,我想让自定义验证程序以某种方式告诉控制器返回404,如果它无法在数据库中找到匹配的用户。

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

如:

User.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 
       } 
      } 
     } 
    } 
} 

回答

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的总体思路。

+1

谢谢,我的意思是更新。这看起来很有希望 –

+0

你能解释一下,或者指点我的一些文档来解释'withUser'方法中的'id =“id”'参数吗?我不知道我害怕什么。 –

+1

这只是一个可以覆盖的变量。所以如果你想通过一个不同的参数来查找一个对象,你将它作为id传入,而不是默认的“id”。 – Gregg

0

也许你应该尝试返回404,但那么实际的错误,你解析和做别的事情与

你不会有大量的错误代码与我玩n中的第一个实例(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"