You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Java @NotNull校验违规信息显示其他约束的具体参数值?

问题描述

现有username字段需满足以下约束:

  • 非空
  • 长度在4-64字符之间
  • 匹配正则表达式[A-Za-z0-9]+

当字段为null时,默认错误消息仅显示must not be null,期望显示完整组合消息:must not be null AND length must be between 4 and 64 characters AND must match "[A-Za-z0-9]+"。

初始代码配置

@NotNull
@Length(min = 4, max = 64)
@Pattern(regexp = "[A-Za-z0-9]+")
String username;

尝试修改后的代码

@NotNull(message = """{
        jakarta.validation.constraints.NotNull.message} 
        AND {org.hibernate.validator.constraints.Length.message} 
        AND {jakarta.validation.constraints.Pattern.message}""")
@Length(min = 4, max = 64)
@Pattern(regexp = "[A-Za-z0-9]+")
String username;

遇到的问题

修改后错误消息中的min、max、regexp等参数未被渲染为实际值:

ConstraintViolationImpl{
  interpolatedMessage='must not be null AND length must be between {min} and {max} AND must match "{regexp}"',
  propertyPath=username, rootBeanClass=class app.User,
  messageTemplate='{jakarta.validation.constraints.NotNull.message} AND {org.hibernate.validator.constraints.Length.message} AND {jakarta.validation.constraints.Pattern.message}'}

如何让错误消息显示这些参数的真实值?


解决方案

消息插值仅会处理当前约束注解的参数,跨注解引用其他约束的消息模板时,不会自动替换其他注解的参数。可以通过以下方式实现需求:

方式一:硬编码参数值到消息中

直接将长度范围和正则表达式写死到@NotNull的消息里,适合参数固定的场景:

@NotNull(message = "must not be null AND length must be between 4 and 64 characters AND must match \"[A-Za-z0-9]+\"")
@Length(min = 4, max = 64)
@Pattern(regexp = "[A-Za-z0-9]+")
String username;

方式二:自定义组合约束注解

若参数需要动态调整,建议自定义整合三个约束的注解,在消息模板中显式引用自定义参数:

  1. 定义组合注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@NotNull
@Length(min = 4, max = 64)
@Pattern(regexp = "[A-Za-z0-9]+")
@Constraint(validatedBy = {})
public @interface ValidUsername {
    String message() default "must not be null AND length must be between {lengthMin} and {lengthMax} characters AND must match \"{patternRegexp}\"";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    // 定义可引用的参数
    int lengthMin() default 4;
    int lengthMax() default 64;
    String patternRegexp() default "[A-Za-z0-9]+";
}
  1. 使用自定义注解
@ValidUsername
String username;

这种方式可集中管理参数,后续修改约束只需调整注解默认值,无需修改消息模板。

方式三:自定义消息插值器(复杂场景)

若需更灵活的消息处理,可自定义MessageInterpolator实现跨注解参数插值,但该方式复杂度高,仅推荐用于复杂场景。


内容的提问来源于stack exchange,提问作者O1G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:50:46