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

使用@NotNull注解约束校验时,能否返回默认消息的键而非消息内容?

如何让@NotNull校验返回消息键而非默认消息内容?

当我们使用@NotNull注解进行约束校验时,系统会自动返回解析后的默认消息内容。以下是@NotNull注解的具体实现代码:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {

    String message() default "{jakarta.validation.constraints.NotNull.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };

    /**
     * Defines several {@link NotNull} annotations on the same element.
     *
     * @see jakarta.validation.constraints.NotNull
     */
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Documented
    @interface List {

        NotNull[] value();
    }
}

请问是否存在某种方式,让校验返回的是该消息对应的键,即jakarta.validation.constraints.NotNull.message?


解决方案

有两种可行方案可以实现这一需求:

1. 自定义MessageInterpolator(全局生效)

Bean Validation的消息解析逻辑由MessageInterpolator接口控制,我们可以实现该接口,跳过消息解析步骤,直接返回原始的消息键:

import jakarta.validation.MessageInterpolator;
import jakarta.validation.MessageInterpolator.Context;
import java.util.Locale;

public class KeyOnlyMessageInterpolator implements MessageInterpolator {
    @Override
    public String interpolate(String messageTemplate, Context context) {
        // 移除消息模板中的大括号,返回纯键值
        return messageTemplate.replace("{", "").replace("}", "");
    }

    @Override
    public String interpolate(String messageTemplate, Context context, Locale locale) {
        return interpolate(messageTemplate, context);
    }
}

在Spring Boot环境中,通过配置类替换默认的插值器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;

@Configuration
public class ValidationConfig {
    @Bean
    public Validator validator() {
        ValidatorFactory factory = Validation.byDefaultProvider()
                .configure()
                .messageInterpolator(new KeyOnlyMessageInterpolator())
                .buildValidatorFactory();
        return factory.getValidator();
    }
}

2. 自定义注解(局部生效)

创建一个替代@NotNull的自定义注解,直接将message默认值设为目标键,且不使用大括号包裹(避免系统解析):

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {})
public @interface NotNullWithKey {
    String message() default "jakarta.validation.constraints.NotNull.message";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        NotNullWithKey[] value();
    }
}

使用时将原有代码中的@NotNull替换为@NotNullWithKey即可,适合不需要全局修改校验逻辑的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:45:41