2016-04-07 31 views
1

我正在嘗試在grails中進行一些serverside驗證,並將我的錯誤作爲json由angularjs處理返回到前端。Grails rejectvalue錯誤和域錯誤驗證

錯誤條件

Department - required 
Department - unique 
Description - foobar not allowed 

我有下面的代碼。

控制器

def saveDepartment() { 
    def errors = [] 
    def success = true  
    def department 

    try{ 
     department = departmentService.save(request.JSON); 

     if(department.hasErrors()) { 
      success = false 
      errors = department.errors.fieldErrors;   
     }   
    } catch(Exception e){ 
     e.printStackTrace() 
     errors = "Unknown" 
     success = false 

     if(log.errorEnabled){ 
      log.error("save department encountered unknown error: ", e) 
     } 

     response.status = 500 
    } finally { 
     respond ([success:success, errors:errors, department:department]) as JSON; 
    } 
} 

服務

def save(jsonObj) { 
    def dept = new Department(); 
    dept.setName(jsonObj.name);  
    dept.setDescription(jsonObj.description); 

    if(dept.description.equals('foobar')) { 
     dept.errors.rejectValue('description', 'foobar', 'Foobar is not allowed') 
    } 

    if (!dept.save()) { 
     dept.discard(); 
    } 

    return dept; 
} 

服務方法嘗試2調試代碼

def save(jsonObj) { 
    def dept = new Department(); 
    dept.setName(jsonObj.name); 
    dept.setDescription(jsonObj.description); 

    if(dept.description.equals('foobar')) { 
     println 'rejected value ' 
     dept.errors.rejectValue('description', 'foobar', 'Foobar is not allowed') 
    } 

    println 'dept errors ' + dept.errors.allErrors.size(); 

    if (dept.errors.hasErrors()) { 
     dept.errors.allErrors.each {FieldError error -> 
      println error 
     } 
    } 

    if (!dept.save(true)) { 
     println 'dept errors 2 ' + dept.errors.allErrors.size(); 

     if (dept.errors.hasErrors()) { 
      dept.errors.allErrors.each {FieldError error -> 
       println error 
      } 
     } 
    } 

    return dept; 
} 

輸出

..................rejected value 
dept errors 1 
Field error in object 'org.hri.leaverequest.Department' on field 'description': rejected value [foobar]; codes [foobar.org.hri.leaverequest.Department.descripti 
on,foobar.description,foobar.java.lang.String,foobar]; arguments []; default message [Foobar is not allowed] 
dept errors 2 1 
Field error in object 'org.hri.leaverequest.Department' on field 'name': rejected value [null]; codes [org.hri.leaverequest.Department.name.nullable.error.org.h 
ri.leaverequest.Department.name,org.hri.leaverequest.Department.name.nullable.error.name,org.hri.leaverequest.Department.name.nullable.error.java.lang.String,or 
g.hri.leaverequest.Department.name.nullable.error,department.name.nullable.error.org.hri.leaverequest.Department.name,department.name.nullable.error.name,depart 
ment.name.nullable.error.java.lang.String,department.name.nullable.error,org.hri.leaverequest.Department.name.nullable.org.hri.leaverequest.Department.name,org. 
hri.leaverequest.Department.name.nullable.name,org.hri.leaverequest.Department.name.nullable.java.lang.String,org.hri.leaverequest.Department.name.nullable,depa 
rtment.name.nullable.org.hri.leaverequest.Department.name,department.name.nullable.name,department.name.nullable.java.lang.String,department.name.nullable,nulla 
ble.org.hri.leaverequest.Department.name,nullable.name,nullable.java.lang.String,nullable]; arguments [name,class org.hri.leaverequest.Department]; default mess 
age [Property [{0}] of class [{1}] cannot be null] 

問題

如果部門爲null,並且描述了用foobar的rejectValue,只有一個錯誤, 「部門空」 則返回,foobar的沒有出現在錯誤。

如果部門包含現有值並且說明包含foobar,則返回唯一約束,但foobar不會出現在錯誤中。

如果department具有很好的值並且foobar仍然存在,那麼rejectValue不會阻止保存的發生並且不會引發錯誤。現在,如果在rejectValue之後輸出dept.errors,我可以看到實際存在的錯誤。

目標

我的目標是回到我的所有錯誤,如果錯誤存在未保存到數據庫,我缺少什麼來實現這一目標?

回答

1

你可以這樣來做:

dept.validate() 

if(dept.description.equals('foobar')) { 
    dept.errors.rejectValue('description', 'foobar', 'Foobar is not allowed') 
} 

if(!dept.errors.hasErrors()) { 
    dept.save() 
} 

return dept 
0

當然這是您需要在域類或相關驗證器中正確使用的驗證約束?

您有一組標準,後端的驗證應該與您期望返回或不作爲錯誤相匹配嗎?如果您是基於department.something和字段名,普惠制頁面上,那麼你可能需要調整不及格的 - 或者也許我失去了一些東西

class Example { 
    Department deparment 

    static constraints = { 
    department(nullable:false, blank:false, unique:true, validator: checkDept) 
} 

    static def checkDept= { val, obj, errors -> 
     //department has a value 
     if (val) { 
       //val is now also the same as object.department 
       if (obj.deparment.description='foo') { 
         errors.rejectValue(propertyName, "nullable.input", [''] as Object[], 'this is description as foo being rejected') 
       } else if (obj.deparment.name='bar') { 
         errors.rejectValue('department.name', "nullable.input", [''] as Object[], 'this is name of bar) 

     } else { 
      errors.rejectValue(propertyName, "nullable.input", [''] as Object[], 'this is null and being rejected') 
     } 
    } 

} 

propertyName的會結合實際對象的名字。

上述邏輯並不完全符合您的要求,但它應該讓您瞭解如何自定義您想要失敗的內容。如果不匹配則只會經歷,你需要