我有一个具有类型为String
的字段的实体,在该字段上我定义了一个@Pattern
注释,强制执行与给定正则表达式匹配的字段内容。现在我想知道,是否可以参数化约束,例如在定义的验证错误消息中显示与正则表达式不匹配的第一个字符。
更糟糕的是,要显示的约束违反错误消息不是直接在注释中定义的,而是在属性文件中定义的,如下面所示的示例:
示例类:
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做这样的事情吗。验证?我假设@Pattern
注释无法参数化错误消息。但也许可以用参数化的验证消息定义我自己的ConstraintValidator
?
考虑到一些验证注释,如@Size(min=1,max=5)
允许参数化错误消息及其注释参数,如字符串的长度必须为{min}到{max}个字符
,我找到了一个解决方案,可以解决带有占位符的参数化错误消息,例如{0}
,{1}
,…:
定义自己的验证约束,例如:
@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
等添加其他参数:
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. */
}
}
}
即使验证消息是在属性文件(例如)中定义的,此解决方案也可以工作。
parameterizedMessage = Invalid character: Do not use the {0} character.
问题内容: 抱歉,这个问题以前是否已经解决过。如果可以,请将我链接到该文件,但到目前为止,我还没有找到满意的答案。 我一直在寻找能使我的javax验证提供的错误消息更具体的方法。 在ValidationMessages.properties文件中指定了我目前用于@Min批注的消息: 并按预期打印 我想要的是消息还包括验证失败的变量(和类)的名称以及失败的变量的值。所以更像。 任何帮助将不胜感激。
我正在使用注释在SpringMVC中进行验证。。。 我对一个字段使用了两个注释进行验证 @NotEmpty(message=“required”) @大小(最小值为3,最大值为8,消息为超出范围) 私有字符串密码; 我面临的问题是,当字段留空时,它会显示两条错误消息(*必需,并且超出范围)。但我想显示其中一条错误消息,而不是两条。。。 可以用一条消息进行限制吗?如果是,这种情况的可能性是什么? 任
我已经阅读了一些关于如何自定义处理API请求验证错误的答案和问题。然而,这一切似乎有点过头了。我的endpoint中有一个简单的对象: 发送空值或空值时引发的错误是: 这条信息传递给前端有点太多了。他们需要的只是“目标群体不能是空白的”。我想将上面的信息转换为以下内容: 我怎样才能做到这一点?
我正在实现一个生成Kafka消息的过程,每个消息都应该有由模式注册表验证的模式。为了开发,我使用docker运行kafka和模式注册表,我的模式由模式注册表ui进行注册。 看起来我的模式没有被验证或者我缺少一些配置。我的生产者类有以下代码: 大多数时候,我会收到一个错误,如“Schema not found”,当没有引发此异常时,我的消息不会被验证,它只是将消息发送到另一个主题。 是否缺少任何类型
我正在使用Spring Boot 2.1.8构建一个项目,我的POM中有spring-boot-starter-web,我可以看到Maven将hibernate-validator 6.0.17拉到类路径上。 我在资源文件夹中有我的消息,它们似乎可以正确地查找,这样当我更改区域设置时,Spring就可以从正确的文件中加载消息。 my@RESTController中的相关方法采用@Valid和@Re
我在验证JSON时遇到了一些错误。我无法理解这些错误,有人能帮我解释一下吗。 } 这是json。 消息:JSON与“anyOf”中的任何模式都不匹配。架构路径: 消息:无效类型。应为数组,但得到的是字符串。架构路径: 消息:值“标识”载体“未在枚举中定义。架构路径: 消息:字符串“uui # abb 0 ef 56-8562-4056-aa62-AFB 758 a 150 ad”未根据格式“uri