javax.validation.constraints.Pattern注释的参数化错误消息? [英] Parameterized error messages for javax.validation.constraints.Pattern annotation?
问题描述
我有一个实体,其字段为 String
,我在其上定义了一个 @Pattern
注释,强制执行内容匹配给定正则表达式的字段。现在我想知道,是否可以参数化约束,例如在定义的验证错误消息中显示与正则表达式不匹配的第一个字符。
I have an entity with a field of type String
on which I defined a @Pattern
annotation enforcing the content of the field matching a given regular expression. Now I wonder, whether it is possible to parameterize the constraint such as that the first character not matching the regular expression is shown in the defined validation error message.
使其成为可能更糟糕的是,为注释违规而显示的错误消息没有直接在注释中定义,而是在属性文件中定义,如下例所示:
To make it even worse, the error message to be shown for the constraint violation is not defined in the annotation directly, but within a properties file, as in the example shown below:
示例class:
public class Address {
@Pattern(regexp="[a-zA-Z]*", message="paremeterizedMessage")
private String street;
}
示例属性文件:
parameterizedMessage = Invalid character {0}. Only characters a-z, A-Z allowed.
是否可以使用javax.validation执行此类操作?我假设 @Pattern
注释无法参数化错误消息。但也许可以使用参数化验证消息定义我自己的 ConstraintValidator
?
Is it possible to do such a thing with javax.validation? I assume that the @Pattern
annotation is not able to parameterize error messages. But maybe it is possible to define my own ConstraintValidator
with parameterized validation messages?
推荐答案
考虑到某些验证注释(例如 @Size(min = 1,max = 5)
允许参数化错误消息及其注释参数,例如字符串的长度必须为{min}到{max}个字符。
,我找到了一个参数化错误消息的解决方案,通常用于占位符,例如 {0 }
, {1}
,...:
Considering the fact that some validation annotations such as @Size(min=1,max=5)
allow for parameterized error messages with their annotation parameters such as The String must have a length of {min} to {max} characters.
, I found a solution for parameterized error messages in general with place holders such as {0}
, {1}
, ...:
定义自己的验证约束例如:
Define an own validation constraint such as:
@Constraint(validatedBy=OnlyCharactersAllowedValidator.class)
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface OnlyCharactersAllowed {
String message() default "parameterizedMessage";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
在验证器类中,反射可用于扩展存储所有的映射 @Size
min 和 max
) >)和其他参数可以为键 0
, 1
等添加:
Within the validator class, reflection can be used to extend a map that stores all the annotation parameters (such as min
and max
for @Size
) and additional parameters can be added for the keys 0
, 1
etc.:
public class OnlyCharactersAllowedValidator implements ConstraintValidator<OnlyCharactersAllowed,String>
{
private static final String validCharacters = "abcdefghijklmnopqrstuvwxyz";
@Override
public boolean isValid(String text, ConstraintValidatorContext constraintContext)
{
for (int index = 0; index < text.length; index++) {
String aCharacter = text.substring(index, index+1);
if (validCharacters.indexOf(aCharacter) < 0) {
/* Within this message call the magic happens: {0} is mapped to the invalid character. */
addMessageParameter(constraintContext, aCharacter);
/* Create violation message manually and suppress the default message. */ constraintContext.buildConstraintViolationWithTemplate(constraintContext.getDefaultConstraintMessageTemplate()).addConstraintViolation();
constraintContext.disableDefaultConstraintViolation();
/* No further validation: show only one error message for invalid characters. */
break;
}
}
}
private void addMessageParameter(ConstraintValidatorContext constraintContext, Object... parameter)
{
try
{
/* Get map for parameters (reflection necessary). */
Field descriptorField = ConstraintValidatorContextImpl.class.getDeclaredField("constraintDescriptor");
descriptorField.setAccessible(true);
@SuppressWarnings("unchecked")
ConstraintDescriptorImpl<OnlyCharactersAllowed> descriptor = (ConstraintDescriptorImpl<OnlyCharactersAllowed>) descriptorField.get(constraintContext);
Map<String,Object> attributes = descriptor.getAttributes();
/* Copy immutable Map to new Map. */
Map<String,Object> newAttributes = new HashMap<String,Object>(attributes.size() + parameter.length);
for (String key : attributes.keySet())
{
newAttributes.put(key, attributes.get(key));
}
/* Add given parameters to attributes. */
Integer parameterCounter = 0;
for (Object param : parameter)
{
newAttributes.put(parameterCounter.toString(), param);
parameterCounter++;
}
/* Set new Map in Descriptor (reflection necessary). */
Field attributesField = ConstraintDescriptorImpl.class.getDeclaredField("attributes");
attributesField.setAccessible(true);
attributesField.set(descriptor, newAttributes);
}
catch (NoSuchFieldException | IllegalAccessException | SecurityException | ClassCastException e1)
{
/* Do nothing in case of exception. Unparameterized message is shown. */
}
}
}
此解决方案即使有效如果您的验证消息是在属性文件中定义的,例如。
This solution even works if your validation message is defined in a properties file such as.
parameterizedMessage = Invalid character: Do not use the {0} character.
这篇关于javax.validation.constraints.Pattern注释的参数化错误消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!