Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Constraint Validator Annotation Not Being Executed

After a lot of surfing, looking here on SO, reading articles and trying numerous things, for some reason my custom constraint in my Spring-based web service app is not firing. I can't seem to figure this one out so I am polling the audience.

I am using Jetty 9.2.2.v20140723. Spring 4.3.13, Hibernate 5.3.0-FINAL. Following are my files. At this point I am trying to implement cross-parameter validation. The example is trivial: if the two params are not equal, validation fails. Files:

package com.xxx.yyy;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import com.xxx.validator.ValuesValidator;

public interface IGetValues {

   @Path("/{value1}/{value2}")
   @GET
   @ValuesValidator
   public MyResponse getValues(@PathParam("value1") String value1, @PathParam("value2") String value2);

}

Next:

package com.xxx.yyy;

import org.springframework.stereotype.Component;
import com.xxx.validator.ValuesValidator;

@Component
public class GetValuesImpl implements IGetValues {

  @Override
  @ValuesValidator
  public MyResponse getValues(String value1, String value2) {
    return new MyResponse();
  }
}

Next:

package com.xxx.yyy.validator;

import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraintvalidation.SupportedValidationTarget;


@Target({METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = ValuesValidatorImpl.class)
@Documented
@SupportedValidationTarget(ValidationTarget.PARAMETERS)

public @interface ValuesValidator {
 String message() default "The two values don't match";
 Class<?>[] groups() default {};
 Class<? extends Payload>[] payload() default {};
}

Next:

package com.xxx.yyy.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;


@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class ValuesValidatorImpl implements 
   ConstraintValidator<ValuesValidator, Object[]> {

    @Override
    public void initialize(ValuesValidator valuesValidator) {

    }

    @Override
    public boolean isValid(Object[] values, ConstraintValidatorContext constraintValidatorContext) {

      String val1 = (String) values[0];
      String val2 = (String) values[1];

      return val1.equals(val2);
   }
}

I am using PostMan to GET the URL:

http://localhost:9086/path/v1/values/A/B

Since "A" is not "B", I ought to get a validation exception thrown and some kind of "You Suck!" code back. No suck luck.

The service is invoked just fine and I get a response as expected from MyResponse. However the validator is not being fired. That is for sure. I have used System.outs, breakpoints, etc. It just ain't happening.

One source said to make a @Configuration class and add an @Bean getter to it that returned a ValuesValidatorImpl object. Tried that, it no work. I added it to the component-scan package too declared in my applicationContext.xml file.

Any suggestions folks? "It works fine in the example" just doesn't seem to be happening here this time.

UPDATE: I posted my issue to the Jetty Users list and a member asked for an example implementation of the problem avail. on Github so I obliged. To reproduce the problem behavior please see:

https://github.com/mcc99/samples/tree/master/customer-validator

Developed with IntelliJ IDEA Community and includes a Maven .pom file for easy dependency examination and retrieval.

And thank you in advance for any swipes you may decide to take on the issue. I have a hard time believing it's a problem that has not surfaced by now so I am obliged to imagine I am doing something wrong/missing something. Also be aware I have tried the most recent ver. of Jetty and the problematic behavior continues.

like image 759
Matt Campbell Avatar asked May 17 '26 06:05

Matt Campbell


1 Answers

You must add annotation @Validated on your target bean.

import org.springframework.validation.annotation.Validated;

//..
@Component
@Validated
public class GetValuesImpl implements IGetValues {

Otherwise, this bean will not have attached the custom validation you provided.

like image 180
Adina Rolea Avatar answered May 18 '26 20:05

Adina Rolea