Matt Campbell
2018-10-12 16:19:35 UTC
Please forgive me if this has been fielded before. I can't imagine it hasn't. I am trying to implement a custom validator in a REST services app using Jetty as the server. The validator annotations despite dependencies being declared simply are not being initialized at all. This is driving me crazy. I have scoured the web for info about this but cannot find anything that addresses it.
My .pom file includes:
---
.
.
.
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
<scope>provided</scope>
</dependency>
.
.
.
---
Also under <plugins> I have:
---
.
.
.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin-version}</version>
<configuration>
<jvmArgs>-Xmx2048m -Xms512m -XX:MaxPermSize=512m</jvmArgs>
<httpConnector>
<port>9086</port>
</httpConnector>
<stopPort>9968</stopPort>
<stopKey>jetty-stop</stopKey>
<stopWait>10</stopWait>
<webApp>
<contextPath>/customer</contextPath>
</webApp>
<useTestScope>true</useTestScope>
</configuration>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
</dependencies>
</plugin>
.
.
.
---
Just to try to get it working I have a service that takes two URL parameters and checks to see if they are the same. If not, the validation fails. The validator interface class:
----
package com.xxx.customer.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;
@Target({METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = Countries2ValidatorImpl.class)
@Documented
public @interface Countries2Validator {
String message() default "The two country code values don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
---
The validator impl:
---
package com.xxx.customer.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class Countries2ValidatorImpl implements ConstraintValidator<Countries2Validator, Object[]> {
@Override
public void initialize(Countries2Validator countries2Validator) {
}
@Override
public boolean isValid(Object[] values, ConstraintValidatorContext constraintValidatorContext) {
String countryCode = (String) values[0];
String anotherValue = (String) values[1];
return countryCode.equals(anotherValue);
}
}
---
Service interface class:
---
package com.xxx.customer.jaxrs.countries;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import com.xxx.api.address.v1.Countries;
import com.xxx.api.address.v1.Country;
import com.xxx.customer.validator.Countries2Validator;
public interface CountriesRS {
@Path("/{countryCode}/{anotherValue}")
@GET
@Countries2Validator
Response getCountryByCode2(@PathParam("countryCode") String countryCode, @PathParam("anotherValue") String anotherValue);
}
---
Srvc impl class:
---
package com.xxx.customer.jaxrs.countries;
import org.springframework.stereotype.Component;
import com.xxx.customer.validator.Countries2Validator;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Component
public class CountriesRSImpl implements CountriesRS {
@Override
@Path("/{countryCode}/{anotherValue}")
@GET
@Countries2Validator
public Response getCountryByCode2(String countryCode, String anotherValue) {
return Response.ok("OK").build();
}
}
---
I am calling the service using Postman. The URL is: http://localhost:9086/customer/v1/countries/UaS/USA
I get a 200 response instead of an error. I have added System.out()s to initialize() etc. and nothing is printed to console. This is how I know the validator isn't even being initialized much less called.
My .pom file includes:
---
.
.
.
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
<scope>provided</scope>
</dependency>
.
.
.
---
Also under <plugins> I have:
---
.
.
.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin-version}</version>
<configuration>
<jvmArgs>-Xmx2048m -Xms512m -XX:MaxPermSize=512m</jvmArgs>
<httpConnector>
<port>9086</port>
</httpConnector>
<stopPort>9968</stopPort>
<stopKey>jetty-stop</stopKey>
<stopWait>10</stopWait>
<webApp>
<contextPath>/customer</contextPath>
</webApp>
<useTestScope>true</useTestScope>
</configuration>
<dependencies>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
</dependencies>
</plugin>
.
.
.
---
Just to try to get it working I have a service that takes two URL parameters and checks to see if they are the same. If not, the validation fails. The validator interface class:
----
package com.xxx.customer.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;
@Target({METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = Countries2ValidatorImpl.class)
@Documented
public @interface Countries2Validator {
String message() default "The two country code values don't match";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
---
The validator impl:
---
package com.xxx.customer.validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class Countries2ValidatorImpl implements ConstraintValidator<Countries2Validator, Object[]> {
@Override
public void initialize(Countries2Validator countries2Validator) {
}
@Override
public boolean isValid(Object[] values, ConstraintValidatorContext constraintValidatorContext) {
String countryCode = (String) values[0];
String anotherValue = (String) values[1];
return countryCode.equals(anotherValue);
}
}
---
Service interface class:
---
package com.xxx.customer.jaxrs.countries;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
import com.xxx.api.address.v1.Countries;
import com.xxx.api.address.v1.Country;
import com.xxx.customer.validator.Countries2Validator;
public interface CountriesRS {
@Path("/{countryCode}/{anotherValue}")
@GET
@Countries2Validator
Response getCountryByCode2(@PathParam("countryCode") String countryCode, @PathParam("anotherValue") String anotherValue);
}
---
Srvc impl class:
---
package com.xxx.customer.jaxrs.countries;
import org.springframework.stereotype.Component;
import com.xxx.customer.validator.Countries2Validator;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
@Component
public class CountriesRSImpl implements CountriesRS {
@Override
@Path("/{countryCode}/{anotherValue}")
@GET
@Countries2Validator
public Response getCountryByCode2(String countryCode, String anotherValue) {
return Response.ok("OK").build();
}
}
---
I am calling the service using Postman. The URL is: http://localhost:9086/customer/v1/countries/UaS/USA
I get a 200 response instead of an error. I have added System.out()s to initialize() etc. and nothing is printed to console. This is how I know the validator isn't even being initialized much less called.