我正在使用Hibernate@NotNull验证器,我正在尝试创建自定义消息来告诉用户哪个字段在空时产生了错误。类似这样的东西:
notNull.custom = The field {0} can't be null.
(这将在我的ValidationMessages.properties文件中)。
其中,{0}应该是通过以下方式传递给验证程序的字段名:
@NotNull(field="field name")
我有办法做到吗?
如果您的需求可以通过插入Hibernate消息来满足,那么您可以像这样创建/命名您的*属性文件:
ValidationMessages.properties
在这里面:
javax.validation.constraints.NotNull.message = CUSTOMIZED MESSAGE WHEN NOTNULL is violated!
默认情况下,Hibernate搜索名为ValidationMessages
的ResourceBundle
。还可能涉及区域设置:ValidationMessages\u en
,ValidationMessages\u de
,
Hibernate将通过interpolatedMessage
参数提供您自定义的消息,因此将显示所有ConstraintViolationExc0019
相关信息(包括您的消息)。因此您的消息将是真正异常的一部分。将提供一些笨重的信息!
如果您想创建自定义异常(无默认ConstraintViolationException
行为),请查看以下内容:
使用<代码> GANGIKAOD概念,考虑以下内容
public void saveOrUpdate(IEntity<?> entity) {
try {
if(entity.getId == null) {
em.persist(entity);
} else {
em.merge(entity)l
}
} catch(ConstraintViolationException cve) {
throw new ConstraintViolationEx(constructViolationMessage(cve.getConstraintViolations()));
}
}
private String constructMessage(Set<ConstraintViolation<?>> pConstraintViolations) {
StringBuilder customMessages = new StringBuilder();
for(ConstraintViolation<?> violation : pConstraintViolations) {
String targetAnnotation = violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName();
if(supportsCustomMessage(targetAnnotation)) {
applyMessage(violation, targetAnnotation, customMessages);
} else {
// do something with not customized constraints' messages e.g. append it to existing container
}
}
return customMessages.toString();
}
private void applyMessage(ConstraintViolation<?> pViolation, String pTargetAnnotation, StringBuilder pCustomMessages) {
String targetClass = pViolation.getRootBean().getClass().getName();
String targetField = pViolation.getPropertyPath().toString();
pCustomMessages.append(MessageFormat.format(getMessageByAnnotation(pTargetAnnotation), targetClass, targetField));
pCustomMessages.append(System.getProperty("line.separator"));
}
private String getBundleKey() {
return "ValidationMessages"; //FIXME: hardcoded - implement your true key
}
private String getMessageByAnnotation(String pTargetAnnotation) {
ResourceBundle messages = ResourceBundle.getBundle(getBundleKey());
switch(pTargetAnnotation) {
case "NotNull":
return messages.getString(pTargetAnnotation + ".message");
default:
return "";
}
}
private boolean supportsCustomMessage(String pTargetAnnotation) {
return customizedConstraintsTypes.contains(pTargetAnnotation);
}
产生的结果:
test.model.exceptions.ConstraintViolationEx
test.model.Person : name cannot be null
test.model.Person : surname cannot be null
一个hibernateConstraintViolation
提供了关于根类
和受限字段
的相关信息。如您所见,它适用于所有hibernate支持的约束,因此您需要检查当前注释是否可以由支持自定义CustomMessage(
您需要做的就是实现不受支持的约束逻辑。例如,它可以附加它的原因消息或插入默认消息(真正的异常会进入*日志文件)
要自定义注释消息,需要在isValid()方法中禁用现有的违规消息,并生成新的违规消息并添加它。
constraintContext.disableDefaultConstraintViolation();
constraintContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
在下面给出的示例中,我根据“无效日期”、“不能大于今天日期”和“日期格式是否正确”创建了一个用于输入日期验证的注释。
@CheckDateIsValid(displayPattern = "DD/MM/YYYY", programPattern = "dd/MM/yyyy", groups = Order2.class)
private String fromDate;
注释界面-
public @interface CheckDateIsValid {
String message() default "default message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String displayPattern();
String programPattern();
}
注释实现类-
public class CheckDateIsValidValidator implements ConstraintValidator<CheckDateIsValid, String> {
@Value("${app.country.timeZone}")
private String timeZone;
private String displayPattern;
private String programPattern;
@Override
public void initialize(CheckDateIsValid constraintAnnotation) {
this.displayPattern = constraintAnnotation.displayPattern();
this.programPattern = constraintAnnotation.programPattern();
}
@Override
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
try {
// disable existing violation message
constraintContext.disableDefaultConstraintViolation();
if (object == null) {
return true;
}
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(programPattern);
LocalDateTime time = LocalDate.parse(object, formatter).atStartOfDay();
ZoneOffset zoneOffSet = ZoneOffset.of(timeZone);
OffsetDateTime todayDateTime = OffsetDateTime.now(zoneOffSet);
if (time == null) {
customMessageForValidation(constraintContext, "date is not valid");
return false;
} else if (todayDateTime.isBefore(time.atOffset(zoneOffSet))) {
customMessageForValidation(constraintContext, "can't be greater than today date");
return false;
}
return time != null;
} catch (Exception e) {
customMessageForValidation(constraintContext, "date format should be like " + displayPattern);
return false;
}
}
private void customMessageForValidation(ConstraintValidatorContext constraintContext, String message) {
// build new violation message and add it
constraintContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
}
}
我有一个自定义注释,如下所示 我定义了一个方面来包装实际的方法调用 注释的用法如下所示 到目前为止,这工作得很好,我可以在TestableAspect#InvkeAndLog中实现我的登录。 现在我需要验证eg的索引值不大于10。 我可以在运行时通过更改方面实现来实现,如下所示 但这需要至少调用一次API,而且效率不高。是否有一种方法可以在spring启动应用程序启动时执行此操作?
问题内容: 注释如何与Java一起使用?以及如何创建这样的自定义注释: 基本上,我需要保留的POJO在持久化时像这样进行序列化: 这样,实际的生成/持久对象是这样的: 任何想法如何实现这一点? 问题答案: 如果创建自定义注释,则必须使用此处的 API 示例进行处理。您可以参考如何声明注释。 这是Java中的示例注释声明的样子。 并被称为。 表示您想在运行时保留注释,并且可以在运行时访问它。 表示您
我创建了一个自定义验证属性,我想将其用于 API 控制器 DTO。此属性需要来自已配置选项的值,这就是我在构造函数中注入这些值的原因,以便我以后可以在 和 方法中使用选项服务。 不幸的是,当我想在DTO中将其用作属性时 我收到错误信息 没有给出对应于'MyValidationAttribute.MyValidationAttribute(IOptionsMonitor)'所需形式参数'myOpti
我想用java为创建自定义注释。我想用这个注释比较两个字符串值,比较后会返回一个
我正在开发spring mvc应用程序,我应该在spring mvc validator的基础上应用验证。第一步,我为类和设置控制器添加了注释,效果很好。现在我需要实现自定义验证器来执行复杂的逻辑,但我想使用现有的注释并添加额外的检查。 我的用户类: 我的验证器: 我的控制器: 那么,有可能同时使用自定义验证器和注释吗?如果是,怎么做?
我在代码中使用Lombok自动生成getter和setter代码。我想添加其他个人注释并使用它。 例如,我想添加一个方法来验证列表中是否存在一个键: 创建注释后,我将执行以下操作: