Spring MVC و JSR-303 التحقق من صحة مشروط
-
26-09-2019 - |
سؤال
لدي نموذج أريد التحقق منه. أنه يحتوي على 2 متغيرات العنوان. يجب التحقق من صحة العنوان 1 دائمًا ، يجب التحقق من صحة العنوان 2 بناءً على بعض الشروط
public class MyForm {
String name;
@Valid Address address1;
Address address2;
}
public class Address {
@NotEmpty
private String street;
}
تقوم وحدة التحكم الخاصة بي تلقائيًا بالتحقق من صحة النموذج الخاص بي وربطه
@RequestMapping(...)
public ModelAndView edit(
@ModelAttribute("form")
@Valid
MyForm form,
BindingResult bindingResult,
...)
if(someCondition) {
VALIDATE form.address2 USING JSR 303
المشكلة هي أنه إذا كنت أستخدم مصادق محلي ValidatorFactoryBean ، فلا يمكنني إعادة استخدام كائن BinidingResult الذي يوفره الربيع. لن يعمل الربط ككائن مستهدف لـ "النتيجة" هو "myform" وليس "العنوان"
validate(form.getAddress2(), bindingResult) //won't work
أتساءل ما هو النهج المعياري/النظيف للقيام بالتحقق الشرطي.
كنت أفكر في إنشاء BindingResult جديد برمجيا في وحدة التحكم الخاصة بي.
final BindingResult bindingResultAddress2 = new BeanPropertyBindingResult(address2, "form");
validate(form.getAddress2(), bindingResultAddress2);
ولكن بعد ذلك ، لا يمكن إضافة قائمة الأخطاء التي أحصل عليها من BindingResultAddress2 إلى "BindingResult" العام لأن أسماء الحقول غير صحيحة ("Street" بدلاً من "العنوان 2. ستريت") ولن يعمل الربط.
تتمثل بعض النهج القذرة في تمديد BeanPropertyBindingResult لقبول بعض السلسلة لإلحاق اسم الحقول .. هل لديك نهج أفضل؟
المحلول
النهج القياسي للتحقق من الهياكل الهرمية هو الاستخدام pushNestedPath()
/popNestedPath()
, ، على الرغم من أنني لست متأكدًا من كيفية لعبه مع JSR-303:
bindingResult.pushNestedPath("address2");
validate(form.getAddress2(), bindingResult);
bindingResult.popNestedPath();
نصائح أخرى
لم أجرب نفسي أبدًا ، لكنني أعتقد أن النهج الصحيح هو استخدام مجموعات المدقق.
بادئ ذي بدء ، دعونا نرى @javax.validation.valid API
بمناسبة جمعية متتالية. سيتم التحقق من صحة الكائن المرتبط بواسطة Cascade.
عندما يستخدم Spring Framework valid كعلامة للتحقق من صحة كائنات الأمر ، فإنه يفسد الغرض منه. يجب على Spring بدلاً من ذلك إنشاء تعليق توضيحي خاص بك والذي يحدد المجموعات التي يجب التحقق من صحتها.
لسوء الحظ ، يجب عليك استخدام واجهة برمجة تطبيقات SPRING Native Valitator إذا كنت بحاجة إلى التحقق من صحة بعض المجموعات
public void doSomething(Command command, Errors errors) {
new BeanValidationValidator(SomeUserCase.class, OtherUserCase.class)
.validate(command, errors);
if(errors.hasErrors()) {
} else {
}
}
يمكن تنفيذ BeanValidationValidator
public class BeanValidationValidator implements Validator {
javax.validation.Validator validator = ValidatorUtil.getValidator();
private Class [] groups;
public BeanValidationValidator(Class... groups) {
this.groups = groups;
}
public void validate(Object command, Errors errors) {
Set<ConstraintViolation<Object>> constraintViolationSet = validator.validate(command, groups);
for(ConstraintViolation<Object> constraintViolation: constraintViolationSet) {
errors.rejectValue(constraintViolation.getPropertyPath().toString(), null, constraintViolation.getMessage());
}
}
}