Grails rejectvalue错误和域错误验证

时间:2016-04-07 15:10:17

标签: grails groovy

我正在尝试在grails中进行一些服务器端验证,并将我的错误传递回前端,因为json将由angularjs处理。

错误条件

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;
}

服务方法尝试使用调试代码

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]

问题

如果department为null并且description与rejectValue有foobar,则只返回一个错误“department null”,foobar不会出现在错误中。

如果department包含现有值并且description包含foobar,则返回唯一约束,但foobar不会出现在错误中。

如果部门具有良好的价值且foobar仍然存在,则rejectValue不会阻止保存发生并且不会引发任何错误。现在,如果我在rejectValue之后输出dept.errors,我可以看到错误确实存在。

目标

我的目标是返回所有错误,如果存在错误则不保存到数据库中,为实现该目标我缺少什么?

2 个答案:

答案 0 :(得分:1)

当然,这是您在域类或相关验证器中获得的验证限制吗?

你有一套标准,后端的验证应该不符合您的预期返回或不作为错误?或许我错过了什么

  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将绑定到实际的对象名称 - 如果您基于department.something失败并且字段名称是gsp页面上的字段名称,那么您可能需要调整它。

上述逻辑并不完全符合您的要求,但它应该让您了解如何自定义您想要失败的内容。如果它与那些不匹配,那么它将根据您的需要进行

答案 1 :(得分: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