If you are familiar with the Bean Validation Framework you know that you cannot get the name of a method argument. So if you do a @NotNull constraint on the first argument of a method and the validation fails the getPropertyPath will be something like "arg1".
I would like to create my own version of @NotNull that can take a value e.g. @NamedNotNull( "emailAddress" ). But I can't figure out how to override the #getPropertyPath in my Validator? Is there any way to do this or am I stuck with "arg1" or "arg2", etc.
EDIT
Based on the answer I received I was able to come up with the following implementation that allows me to take the value from my @QueryParam or @PathParam annotations and use those as the property path for Bean Validation annotations like @NotNull.
For Jersey you need to create the following class. Note the implementation of DefaultParameterNameProvider:
public class ValidationConfigurationContextResolver implements ContextResolver<ValidationConfig> {
@Override
public ValidationConfig getContext( final Class<?> type ) {
final ValidationConfig config = new ValidationConfig();
config.parameterNameProvider( new RestAnnotationParameterNameProvider() );
return config;
}
static class RestAnnotationParameterNameProvider extends DefaultParameterNameProvider {
@Override
public List<String> getParameterNames( Method method ) {
Annotation[][] annotationsByParam = method.getParameterAnnotations();
List<String> names = new ArrayList<>( annotationsByParam.length );
for ( Annotation[] annotations : annotationsByParam ) {
String name = getParamName( annotations );
if ( name == null )
name = "arg" + ( names.size() + 1 );
names.add( name );
}
return names;
}
private static String getParamName( Annotation[] annotations ) {
for ( Annotation annotation : annotations ) {
if ( annotation.annotationType() == QueryParam.class ) {
return QueryParam.class.cast( annotation ).value();
}
else if ( annotation.annotationType() == PathParam.class ) {
return PathParam.class.cast( annotation ).value();
}
}
return null;
}
}
}
Then in your RestConfig you need to add the following line:
register( ValidationConfigurationContextResolver.class );
That's it. Now your ConstraintValidationExceptions will contain the name of the QueryParam or PathParam they are annotated with. For example:
public void getUser(
@NotNull @QueryParam( "emailAddress" ) String emailAddress,
@NotNull @QueryParam( "password" ) String password )
{ ... }
If you are familiar with the Bean Validation Framework you know that you cannot get the name of a method argument
That's not quite correct. Bean Validation specifies the concept of a ParameterNameProvider which allows you to provide your own implementation. Hibernate Validator integrates with ParaNamer to provide parameter names. See the Validator online docs for more information. Once Validator supports Java 8, it will also support the Java 8 parameter naming facility.
IMO, you should give ParaNamer a go.