8
votes

I make a model object with some JSR-303 validator annotation:

public class UserInfoBasicModel  implements Serializable{
    @NotNull(message="cannot be null")
    @NotEmpty(message="cannot be empty")
    private String name;
    //getter and setter
    //..ignored..
}

Auto data-binding it in a controller:

@Controller
@RequestMapping("/user")
public class UserController  {
    @RequestMapping(method = RequestMethod.POST, value = "/registry/")
    public String registry(HttpServletRequest request,
            ModelMap modelMap,
            @Valid UserInfoBasicModel userInfoBasicModel,
            BindingResult result)    {
        //...some code here...
    }
}

In the above scenario, it works fine for the validation. But when I encapsulate the model into another object just as below, the validation on UserInfoBasicModel doesn't work anymore:

the Object that encapsulates the UserInfoBasicModel object:

public static class UserUpdateFormTransmitter       {
    @Valid
    private UserInfoBasicModel userInfoBasicModel;
    //getter and setter
    //..ignored..
}

the controller:

@Controller
@RequestMapping("/user")
public class UserController  {
    @RequestMapping(method = RequestMethod.POST, value = "/registry/")
    public String registry(HttpServletRequest request,
            ModelMap modelMap,
            @Valid UserUpdateFormTransmitter userUpdateFormTransmitter,
            BindingResult result)    {
        //...some code here...
    }
}

I'm wondering why doesn't the @valid annotaion works recursively just like what JSR 303: Bean Validation says.Could any one give me a solution so that I can valid my object recursively, thanks a lot!!!!

2
Maybe the second valid can be omitted? The first Valid should cascade through the entire model. - tstorms
I'm doing something very similar with Spring 3.2.4.RELEASE, and adding @Valid to my equivalent to your userInfoBasicModel in UserUpdateFormTransmitter got it working for me. Without it, nested validation was ignored. - Mike Partridge

2 Answers

6
votes

I have never done recursive validation, but according to this its possible simply by tagging the sub-objects with @Valid.

0
votes

My two cents:

1.Try using ModelAttribute like below:

Java file:

@RequestMapping(method = RequestMethod.POST, value = "/registry/")
public String registry(HttpServletRequest request,
            ModelMap modelMap,
            @ModelAttribute("userupdate") @Valid UserUpdateFormTransmitter userUpdateFormTransmitter,
            BindingResult result)

JSP:

<form:form method="POST" name="form1" action="/registry" modelAttribute="userupdate">

2.Ensure that you are using path attribute like

//for recursive access
<form:input type="text" id="name" path="userInfoBasicModel.name" />

instead of

<form:input type="text" id="name" value="${userInfoBasicModel.name}" />