我正在尝试在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,我可以看到错误确实存在。
目标
我的目标是返回所有错误,如果存在错误则不保存到数据库中,为实现该目标我缺少什么?
答案 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