I have an object Foo
that holds a reference to object Bar
that has a reference to object Baz
, and in order for Foo
to be valid, Bar
has to have a valid, non-null reference to Baz
.
The problem is that Bar
doesn't require a valid, non-null Baz
to be valid, so I can't simply put the validation in there, I need it to be within Foo
.
Here's a simple pseudo-version of the class structure I'm talking about:
class Foo {
// Bar needs to have a valid Baz. Something like this would be ideal:
// @HasAValidBaz(message="Baz is required")
Bar bar;
}
class Bar {
// Baz can be null and Bar will still be valid
// But if there _is_ a Baz, it needs to be valid
Baz baz;
}
class Baz {
@NotBlank(message="My String is required")
String myString;
}
I know I can do this with class-level custom validation annotations, but the problem is that those error objects and corresponding messages apply to the class instance and not the field instance, which I need to be able to easily display the error message next to the correct form field.
Is there a good way to do this, or am I stuck with implementing this validation in the controller?
Annotations are nice, but maybe not appropriate in this case. The problem is that annotations are marked on the actual class, meaning you can't really have two types of validation annotations on the same class - which seems to be your issue. It would maybe be more appropriate for you to use the old-school Spring MVC approach of implementing the Spring Validator class. Here's an example:
public class FooValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Foo.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
Foo foo = (Foo) target;
if(foo.getBar() == null) {
errors.rejectValue("bar", "bar[emptyMessage]");
}
else if(foo.getBar().getBaz() == null){
errors.rejectValue("bar.baz", "bar.baz[emptyMessage]");
}
}
}
And your Spring controller is still pretty much the same as it is using annotations:
@Controller
public class FooController {
@InitBinder("foo")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new FooValidator());
}
@RequestMapping(value="fooPage", method = RequestMethod.POST)
public String processSubmit(@Valid Foo foo, BindingResult result, ModelMap m) {
if(result.hasErrors()) {
return "fooPage";
}
...
return "successPage";
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.