One more error: In a comment to my Eclipse / GlassFish / Java EE 6 tutorial, FMora said:

One detail – if you annotate a constraint with @NotNull and then insert a null value via SoapUI, one gets a NPE instead of a constraint violation.

Oh dear, that’s so true and it is a typical case of untested code. Have you ever seen untested code that did not break? I haven’t :)

The problem was in the ValidationInterceptor in that line, where I took the invalid value and called “toString()” on it.

The tutorial is already updated, and from now on the tutorial begins with a version number. The current version is version 1.2, last updated August 13, 2010 – 17:06. The ZIP file with the sources was updated as well.

For your convenience, here is the updated ValidationInterceptor:

package com.manessinger.cookbook.util;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
 
import com.manessinger.cookbook.exception.ConstraintProperty;
import com.manessinger.cookbook.exception.ValidationException;
import com.manessinger.cookbook.exception.ViolationDetail;
 
@Interceptor
public class ValidationInterceptor {
 
    // the factory is expensive but thread-safe
    private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
 
    @AroundInvoke
    public Object intercept(InvocationContext ctx) throws Exception {
        Validator v = factory.getValidator();
        // for all parameters
        for (Object p : ctx.getParameters()) {
            // validate parameter
            Set<ConstraintViolation<Object>> violations = v.validate(p, Default.class);
            if (!violations.isEmpty()) {
                // validation failed, gather details and throw an exception
                List<ViolationDetail> details = new ArrayList<ViolationDetail>();
                for (ConstraintViolation<Object> violation : violations) {
                    ViolationDetail d = new ViolationDetail();
                    // path to violated constraint
                    d.setAttributedItem(violation.getPropertyPath().toString());
                    // what type of constraint, e.g. "Min" or "Pattern"
                    d.setConstraintName(
                        violation.getConstraintDescriptor()
                            .getAnnotation().annotationType().getSimpleName()
                    );
                    // construct list of constraint properties
                    Map<String, Object> violationAttributes 
                        = violation.getConstraintDescriptor().getAttributes();
                    List<ConstraintProperty> properties = new ArrayList<ConstraintProperty>();
                    for (String propertyName : violationAttributes.keySet()) {
                        if (propertyName.matches("^(message|payload|groups|flags)$")) {
                            // skip unwanted property
                            continue;
                        }
                        ConstraintProperty a = new ConstraintProperty();
                        a.setName(propertyName);
                        a.setValue(violationAttributes.get(propertyName).toString());
                        properties.add(a);
                    }
                    d.setConstraintProperties(properties);
                    // the value that violated the constraint
                    Object invalidValue = violation.getInvalidValue();
                    d.setInvalidItemValue((invalidValue != null ? 
                                           invalidValue.toString() : "null"));
 
                    details.add(d);
                }
                throw new ValidationException(details);
            }
        }
        return ctx.proceed();
    }
}
Creative Commons License
This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

   
© 2010 Andreas Manessinger Suffusion theme by Sayontan Sinha