Reputation: 415
So the class I'm doing JSR-303 bean validation on has two fields with the same pattern constraint applied to each:
@Column(name="test_suite_revision")
@XmlElement(name="test_suite_revision")
@NotNull
@Pattern(regexp = "\\d\\d-\\d\\d-\\d\\d\\d\\d", message = "value must be of the form xx-xx-xxxx")
private String revisionTestSuite;
@Column(name="test_revision")
@XmlElement(name="test_revision")
@NotNull
@Pattern(regexp = "\\d\\d-\\d\\d-\\d\\d\\d\\d", message = "value must be of the form xx-xx-xxxx")
private String revisionTest;
IMPORTANT - this class is NOT a form-backing class in a classic Spring MVC webapp but an entity class that lives at the base of a web service. So the validation is occuring in the service.
Now the web client that consumes the web service is a Spring MVC and does have a form-backing bean which ties to a jsp with places to put error messages.
So suppose a user enters an incorrectly-formatted string into one of the two fields. I can trap for it with this pretty standard code snippet
Set<ConstraintViolation<TestCase>> violations = validator.validate( permit);
if( !violations.isEmpty()) {
logger.debug( "basic validation FAILED with " + violations.size() + " errors");
Iterator<ConstraintViolation<TestCase>> iter = violations.iterator();
while( iter.hasNext()) {
ConstraintViolation<TestCase> cv = iter.next();
logger.debug( "invalidValue:" + cv.getInvalidValue());
logger.debug( "message:" + cv.getMessage());
ConstraintDescriptor<?> cd = cv.getConstraintDescriptor();
Map<String, Object> mapp = cd.getAttributes();
for( String keey : mapp.keySet()) {
logger.debug("mapp key:" + keey + ":" + mapp.get(keey));
}
which writes out
basic validation FAILED with 1 errors
invalidValue:050607
message:value must be of the form xx-xx-xxxx
mapp key:message:value must be of the form xx-xx-xxxx
mapp key:payload:[Ljava.lang.Class;@1367702
mapp key:flags:[Ljavax.validation.constraints.Pattern$Flag;@bf5210
mapp key:groups:[Ljava.lang.Class;@a49be5
mapp key:regexp:\d\d-\d\d-\d\d\d\d
Here's the rub: How does one figure out WHICH field failed validation? I can't seem to find a way to extract the field name , "revisionTest" or "revisionTestSuite" from the ConstraintViolation object nor the ConstraintDescritpor object.
the getValidationAppliesTo() method newly available in version 1.1.0.Final of javax.validation-api seems promising but so far this method throws an AbstractMethodError during runtime. Ugh.
TIA,
Still-learning Steve
Upvotes: 0
Views: 2229
Reputation: 2862
See ConstraintViolation#getPropertyPath
method:
/**
* @return the property path to the value from {@code rootBean}
*/
Path getPropertyPath();
Path.Node#getName
will give you the property name. For field names in nested beans, you have walk the path.
Upvotes: 1