2016-09-20 61 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"