2012-10-18 66 views
1

我有一個Spring Security用戶類,它對用戶名和電子郵件有一個唯一的約束。在一個Command類中,我使用「importFrom User」從這個類中導入了所有約束。除了獨特的限制之外,所有約束都按預期工作。導入的唯一約束未得到驗證

但是,當保存用戶唯一約束得到驗證,並顯示錯誤。但是,如果他們在像所有其他限制一樣保存之前得到驗證,那將會很好。

UPDATE

我加入這個控制器:

user.errors.fieldErrors.each { 
    command.errors.rejectValue(it.getField(), it.getCode()) 
} 

似乎是一個骯髒的解決辦法,但它的工作原理。

回答

0

我曾與前唯一約束的問題,所以我在命令對象做了一個自定義的驗證測試,看看它的獨特之處:

Command對象:

class wateverCommand{ 
    .... 
    String username 

    static constraints = { 
     username validator:{value, command -> 
      if(value){ 
       if(User.findByUsername(value){ 
        return 'wateverCommand.username.unique' 
       } 
      } 
     } 
    } 
} 

您的messages.properties中添加一個自定義錯誤信息:

wateverCommand.username.unique The username is taken, please pick a new username 
0

我同意獨特的約束似乎並不總是正確導入。因爲我想,以避免約束體雜波我喜歡的一個襯墊的方法:

validator: {value, command -> (User.findByUsername(value) ? false : true) } 

然後在你的message.properties這將是:

accountCommand.username.validator.error=That username already exists 
1

問得好@克里斯,你的解決方案因爲在域類和命令對象之間共享約束的目標是避免重複驗證邏輯。

我只是補充一點,避免重複字段錯誤和處理域對象中的嵌套字段路徑,像下面這樣的東西可能是必要的。

def save(EntityCreateCommand cmd) { 
    def entity = new Entity(cmd.properties) 
    def someAssociation = new Something(cmd.properties) 
    entity.someAssociation = someAssociation 

    entity.validate() 

    entity.errors.fieldErrors.each { 
     def fieldName = it.field.split("\\.").last() 
     def flattenedCodes = cmd.errors.getFieldErrors(fieldName).codes.flatten() 
     if(cmd.hasProperty(fieldName) && (!flattenedCodes.contains(it.code))) { 
      cmd.errors.rejectValue(fieldName, 
       "entityCreateCommand.${fieldName}.${it.code}") 
     } 
    } 

    if(cmd.errors.hasErrors()) { 
     error handling stuff... 
    } else { 
     business stuff... 
    } 
}