Enterprise Java Development@TOPIC@

Chapter 120. Interceptor Example: Input Normalization and Validation

120.1. EJB Method Creates Contact
120.2. Non-normalized Caller Data
120.3. Partial Solution: Validation API
120.4. PrePersistCheck
120.5. PostNormalizedCheck
120.6. PreNormalizedCheck
120.7. Validator Interceptors
120.8. Normalization Interceptor
120.9. Bean Class
120.10. CDI Activation (bean.xml)
120.11. Example Output
120.12. Summary


  • Callers can provide names using different normalization

  • Name could be missing entirely




  • Activating validation within JPA lifecycle

  • Overriding/specifying pre-persist and pre-update to use custom PrePersistCheck


  • We apply detailed validation checks during PostNormalizationCheck


  • We apply brief sanity check validation prior to normalization

Figure 120.8. Validator Base Class

public class ValidatorInterceptor {

    @Inject
    private Validator validator;
    private Class<?>[] groups;
    
    protected ValidatorInterceptor() {}
    public ValidatorInterceptor(Class<?>[] groups) { this.groups = groups; }
    
    @AroundInvoke
    public Object invoke(InvocationContext ctx) throws Exception {
        logger.debug("validating method: {}, groups: {}", ctx.getMethod(), Arrays.toString(groups));
        //validate each parameter
        for (Object param: ctx.getParameters()) {
            logger.debug("validating param: {}, groups: {}", param, Arrays.toString(groups));
            Set<ConstraintViolation<Object>> violations = validator.validate(param, groups);
            if (!violations.isEmpty()) {
                Exception ex = new InvalidParam(param.toString(), getErrors(violations));
                logger.debug("aborting call, found error: {}", ex.getMessage());
                throw ex;
            }
        }
        return ctx.proceed();
    }
    
    private List<String> getErrors(Set<ConstraintViolation<Object>> violations) {
        List<String> errors = new ArrayList<String>(violations.size());
        for (ConstraintViolation<Object> v: violations) {
            errors.add(v.toString());
        }
        return errors;
    }
}

  • Grabs parameters from InvocationContext

  • Validates each of them against assigned validation group


  • Define @InterceptorBinding (@Validation) and @Interceptor role for CDI

  • Define validation group(s) for base class


  • Defines @InterceptorBinding (@Validator) and @Interceptor role

  • Defines @AroundInvoke for business method

  • Subjects each parameter to normalization rules

  • Details of normalization omitted (initial caps for each name/word)


  • Applies @interceptorBinding annotation (@Validation)

  • Supplies business method

One of several techniques possible


  • Control ordering of interceptors


  • Input hand a correctable, but invalid name

  • Name passed initial pre-normalization validation

  • Name corrected by normalization

  • Name passed post-normalization validation

  • Name passed pre-persist validation

  • Contac persisted