Как я могу динамически разрешить параметры сообщения с помощью hibernate vadytor?
-
16-10-2019 - |
Вопрос
Я использую валидатор Hibernate и хотел бы разрешить имя категории в сообщении об ошибке. Рассмотрим этот простой сценарий:
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.
Предположим, что у меня есть рабочая реализация HazardousCategoryConstraint. Валидатор проверяет имя каждой категории по списку ограниченных имен. Когда я звоню Validate (InventoryReport), я получаю количество ошибок, которые я ожидаю, за исключением того, что они та же строка. Я хотел бы, чтобы имя категории было разрешено в каждом сообщении. Может ли кто -нибудь указать мне на пример того, как динамически разрешить параметры или показать мне, как?
Решение
ИМО, простым решением является создание пользовательской реализации javax.validation.MessageInterpolator
. Анкет Делегировать основную работу с гибелью WALICENTATOR ResourceBundleMessageInterpolator
и сделать необходимую замену работы в 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();
}
}
@Тест
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());
}
}
Выход
s is a product in the hazardous category list.