简体   繁体   中英

How can I validate a field of a object on my domain object in Spring MVC?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM