Zeeshan
Zeeshan

Reputation: 12421

Multiple Spring MVC validator for the same Controller

I am having a Spring controller with a Validator defined as:

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(new MyValidator(myService));
    }

And calling it:

public ResponseEntity<?> executeSomething(
   @ApiParam(name = "monitorRequest", required = true, value = "") @Valid @RequestBody MonitorRequest monitorRequest,
   HttpServletRequest request, HttpServletResponse response) throws RESTException

I need to add one more Validator for this controller that could be called from some specific methods of this controller. Is there any way to achieve this?

EDIT: I am handling the Error by:

@ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseEntity<?> processValidationError(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        ValidationErrorObj obj =  processFieldErrors(fieldErrors);
        ResponseEntity r = new ResponseEntity(obj, HttpStatus.BAD_REQUEST);
        return r;
    }

Upvotes: 0

Views: 3849

Answers (2)

Prakhar
Prakhar

Reputation: 1075

For those who are still trying to figure out how to solve this in 2017. I was facing similar issues while trying to implement 2 validators in my RestController. I followed the approach mentioned above by @Serge Ballasta.

I ended up making 2 Model each of linked to their specific Validators. The Controller methods look something like

@RequestMapping(value = "register", method = RequestMethod.POST)
public ResponseEntity<User> register(@Valid @RequestBody UserRegisterRequest userRegisterRequest) {
    return null;
}

@RequestMapping(value = "test", method = RequestMethod.POST)
public ResponseEntity<?> test(@Valid @RequestBody TestRequest testRequest) {
    return null;
}

and I created 2 initBinders to wire these validators in the controller like

@InitBinder("testRequest")
public void setupBinder(WebDataBinder binder) {
    binder.addValidators(testValidator);
}

@InitBinder("userRegisterRequest")
public void setupBinder1(WebDataBinder binder) {
    binder.addValidators(userRegistrationRequestValidator);
}

Please note that the @RequestBody attributes (userRegisterRequest , testRequest) had to be provided as values in the @InitBinder() annotations.

By the way the in my code I handle the bindingResult in a custom ExceptionHandler class which extends ResponseEntityExceptionHandler which gives me freedom to do custom handling of the response.

Upvotes: 4

Serge Ballesta
Serge Ballesta

Reputation: 148890

You can have more than one InitBinder method in a controller. It is controlled by the optional value parameter . For the javadoc of InitBinder : String[] value : The names of command/form attributes and/or request parameters that this init-binder method is supposed to apply to ... Specifying model attribute names or request parameter names here restricts the init-binder method to those specific attributes/parameters, with different init-binder methods typically applying to different groups of attributes or parameters.

Another way would be to explicely call a complementary Validator in specific methods.

BTW : I can't see any Errors or BindingResult in your controller method signature : where do you find whether errors occured ?

Upvotes: 4

Related Questions