title: Spring Boot : Custom Validation in Request Params
body: <p>I want to validate one of the request parameters in my controller . The request parameter should be from one of the list of given values , if not , an error should be thrown . In the below code , I want the request param orderBy to be from the list of values present in @ValuesAllowed.</p>
  
  <pre class="lang-java prettyprint-override"><code>@RestController
  @RequestMapping("/api/opportunity")
  @Api(value = "Opportunity APIs")
  @ValuesAllowed(propName = "orderBy", values = { "OpportunityCount", "OpportunityPublishedCount", "ApplicationCount",
          "ApplicationsApprovedCount" })
  public class OpportunityController {
  
  @GetMapping("/vendors/list")
      @ApiOperation(value = "Get all vendors")
  
      public ResultWrapperDTO getVendorpage(@RequestParam(required = false) String term,
              @RequestParam(required = false) Integer page, @RequestParam(required = false) Integer size,
              @RequestParam(required = false) String orderBy, @RequestParam(required = false) String sortDir) {
  </code></pre>
  
  <p>I have written a custom bean validator but somehow this is not working . Even if am passing any random values for the query param , its not validating and throwing an error.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Repeatable(ValuesAllowedMultiple.class)
  @Target({ElementType.TYPE})
  @Retention(RetentionPolicy.RUNTIME)
  @Constraint(validatedBy = {ValuesAllowedValidator.class})
  public @interface ValuesAllowed {
  
      String message() default "Field value should be from list of ";
      Class&lt;?&gt;[] groups() default {};
      Class&lt;? extends Payload&gt;[] payload() default {};
  
      String propName();
      String[] values();
  }
  </code></pre>
  
  <pre class="lang-java prettyprint-override"><code>public class ValuesAllowedValidator implements ConstraintValidator&lt;ValuesAllowed, Object&gt; {
  
      private String propName;
      private String message;
      private String[] values;
  
      @Override
      public void initialize(ValuesAllowed requiredIfChecked) {
          propName = requiredIfChecked.propName();
          message = requiredIfChecked.message();
          values = requiredIfChecked.values();
      }
  
      @Override
      public boolean isValid(Object object, ConstraintValidatorContext context) {
          Boolean valid = true;
          try {
              Object checkedValue = BeanUtils.getProperty(object, propName);
  
              if (checkedValue != null) {
                  valid = Arrays.asList(values).contains(checkedValue.toString().toLowerCase());
              } 
  
              if (!valid) {
                  context.disableDefaultConstraintViolation();
                  context.buildConstraintViolationWithTemplate(message.concat(Arrays.toString(values)))
                          .addPropertyNode(propName).addConstraintViolation();
              }
          } catch (IllegalAccessException e) {
              log.error("Accessor method is not available for class : {}, exception : {}", object.getClass().getName(), e);
              return false;
          } catch (NoSuchMethodException e) {
              log.error("Field or method is not present on class : {}, exception : {}", object.getClass().getName(), e);
              return false;
          } catch (InvocationTargetException e) {
              log.error("An exception occurred while accessing class : {}, exception : {}", object.getClass().getName(), e);
              return false;
          }
          return valid;
      }
  }
  </code></pre>