IMO, giải pháp đơn giản là tạo triển khai tùy chỉnh javax.validation.MessageInterpolator
. Ủy quyền công việc chính cho ResourceBundleMessageInterpolator
của Hibernate Validator và thực hiện công việc thay thế theo yêu cầu trong 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.
gì bạn yêu cầu là: làm thế nào để đặt một giá trị trong chuỗi thông báo lỗi? - điều này có đúng không? – Ralph
@Ralph - đó là chính xác, nhưng cụ thể hơn tôi muốn nó là năng động. Tôi có nhiều trường hợp Danh mục có tên duy nhất. –
Nhưng tên bạn muốn đặt trong thông báo được xác định cho người xác thực của bạn, đúng không? – Ralph