title: Implementing custom validation logic for a spring boot endpoint using a combination of JSR-303 and Spring's Validator
body: <p>I'm trying to implement some custom validation logic for a spring boot endpoint using a combination of <code>JSR-303 Bean Validation API</code> and <code>Spring's Validator</code>.</p>
  
  <p>Based on the Validator class diagram it appears to be possible to extend one of <code>CustomValidatorBean</code>, <code>SpringValidatorAdapter</code> or <code>LocalValidatorFactoryBean</code> to add some custom validation logic into an overridden method <code>validate(Object target, Errors errors)</code>.</p>
  
  <p><a href="https://i.stack.imgur.com/HU4JT.png" rel="noreferrer"><img src="https://i.stack.imgur.com/HU4JT.png" alt="Validator class diagram"></a>.</p>
  
  <p>However, if I create a validator extending any of these three classes and register it using <code>@InitBinder</code> its <code>validate(Object target, Errors errors)</code> method is never invoked and no validation is performed. If I remove <code>@InitBinder</code> then a default spring validator performs the <code>JSR-303 Bean Validation</code>.</p>
  
  <p>Rest controller:</p>
  
  <pre><code>@RestController
  public class PersonEndpoint {
  
      @InitBinder("person")
      protected void initBinder(WebDataBinder binder) {
          binder.setValidator(new PersonValidator());
      }
  
      @RequestMapping(path = "/person", method = RequestMethod.PUT)
      public ResponseEntity&lt;Person&gt; add(@Valid @RequestBody Person person) {
  
          person = personService.save(person);
          return ResponseEntity.ok().body(person);
      }
  }
  </code></pre>
  
  <p>Custom validator:</p>
  
  <pre><code>public class PersonValidator extends CustomValidatorBean {
  
      @Override
      public boolean supports(Class&lt;?&gt; clazz) {
          return Person.class.isAssignableFrom(clazz);
      }
  
      @Override
      public void validate(Object target, Errors errors) {
          super.validate(target, errors);
          System.out.println("PersonValidator.validate() target="+ target +" errors="+ errors);
      }
  
  }
  </code></pre>
  
  <p>If my validator implements <code>org.springframework.validation.Validator</code> then its  <code>validate(Object target, Errors errors)</code> method is called but <code>JSR-303 Bean Validation</code> is not performed prior to it. I can implement my custom JSR-303 validation similar to the way <code>SpringValidatorAdapter</code> implements its <code>JSR-303 Bean Validation</code> but there has to be a way to extend it instead:</p>
  
  <pre><code>    @Override
      public void validate(Object target, Errors errors) {
          if (this.targetValidator != null) {
              processConstraintViolations(this.targetValidator.validate(target), errors);
          }
      }
  </code></pre>
  
  <p>I have looked at using custom JSR-303 constraints to avoid using <code>org.springframework.validation.Validator</code> all together but there must be a way to make a custom validator work.</p>
  
  <p>Spring <a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html" rel="noreferrer">validation documentation</a> is not super clear on combining the two:</p>
  
  <blockquote>
    <p>An application can also register additional Spring Validator instances per DataBinder instance, as described in Section 9.8.3, “Configuring a DataBinder”. This may be useful for plugging in validation logic without the use of annotations.</p>
  </blockquote>
  
  <p>And then later on it touches on configuring multiple Validator instances </p>
  
  <blockquote>
    <p>A DataBinder can also be configured with multiple Validator instances via dataBinder.addValidators and dataBinder.replaceValidators. This is useful when combining globally configured Bean Validation with a Spring Validator configured locally on a DataBinder instance. See ???.</p>
  </blockquote>
  
  <p>I'm using spring boot 1.4.0.</p>