Domanda

Sto usando Hibernate Validator e vorrei risolvere nome della categoria in un messaggio di errore. Si consideri questo scenario semplice:

public class Category {
    private String name;
}

public class Product {
    @HazardousCategoryConstraint(message = "{haz.cat.error}")
    private Category category;
    private String name;
}

public class InventoryReport {
    @Valid
    private List<Product> products;
}


ValidationMessages.properties
haz.cat.error={name} is a product in the hazardous category list.

Si supponga che ho un'implementazione di lavoro di HazardousCategoryConstraint. I validatore controlla il nome di ogni categoria con un elenco di nomi con restrizioni. Quando chiamo validate (InventoryReport) ottengo il numero di errori mi aspetto eccetto quando sono la stessa stringa. Mi piacerebbe vedere il nome della Categoria risolto in ogni messaggio. Qualcuno mi può punto ad un esempio di come risolvere i parametri in modo dinamico, o mostrarmi come?

È stato utile?

Soluzione

IMO, la soluzione più semplice è quella di creare un'implementazione personalizzata di javax.validation.MessageInterpolator. Delegare il lavoro principale per ResourceBundleMessageInterpolator di Hibernate Validator e fare il lavoro di sostituzione richiesto CustomMessageInterpolator.

public class CustomMessageInterpolator extends org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator {

    private static final Pattern MESSAGE_PARAMETER_PATTERN = Pattern.compile( "(\\{[^\\}]+?\\})" );

    @Override
    public String interpolate(String message, Context context) {
        String resolvedMessage = super.interpolate(message, context);
        resolvedMessage = replacePropertyNameWithPropertyValues(resolvedMessage, context.getValidatedValue());
        return resolvedMessage;
    }

    private String replacePropertyNameWithPropertyValues(String resolvedMessage, Object validatedValue) {
        Matcher matcher = MESSAGE_PARAMETER_PATTERN.matcher( resolvedMessage );
        StringBuffer sb = new StringBuffer();

        while ( matcher.find() ) {
            String parameter = matcher.group( 1 );

            String propertyName = parameter.replace("{", "");
            propertyName = propertyName.replace("}", "");

            PropertyDescriptor desc = null;
            try {
                desc = new PropertyDescriptor(propertyName, validatedValue.getClass());
            } catch (IntrospectionException ignore) {
                matcher.appendReplacement( sb, parameter );
                continue;
            }

            try {
                Object propertyValue = desc.getReadMethod().invoke(validatedValue);
                matcher.appendReplacement( sb, propertyValue.toString() );
            } catch (Exception ignore) {
                matcher.appendReplacement( sb, parameter );
            }
        }
        matcher.appendTail( sb );
        return sb.toString();
    }

}

@Test

public void validate() {
        Configuration<?> configuration = Validation.byDefaultProvider().configure();
        ValidatorFactory validatorFactory = configuration.messageInterpolator(new CustomMessageInterpolator()).buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();

        Product p = new Product();
        Category cat = new Category();
        cat.setName("s"); //assume specified name is invalid
        p.setCategory(cat);

        Set<ConstraintViolation<Product>> violations = validator.validate(p);
        for(ConstraintViolation<Product> violation : violations) {
            System.out.println(violation.getMessage());
        }
    }

Output

s is a product in the hazardous category list.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top