如何将nameId的校验注解合并为自定义@NameId注解?
解决自定义@NameId校验注解不生效的问题
你的自定义注解写法不符合Spring Validation规范,直接叠加@Valid和@Pattern无法触发校验逻辑。按以下步骤重构即可解决:
1. 正确定义@NameId约束注解
用@Constraint标记自定义注解,同时复用@Pattern的校验规则,还要满足约束注解的标准属性要求:
import jakarta.validation.Constraint; import jakarta.validation.Payload; import jakarta.validation.constraints.Pattern; import java.lang.annotation.*; @Documented @Constraint(validatedBy = {}) // 复用@Pattern的校验逻辑,无需自定义校验器 @Pattern(regexp = REGEX_PATTERN_ALPHANUMERIC, message = "{error.invalid.name.id.header}") @Target({ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface NameId { // 标准约束注解必须包含的三个属性 String message() default "{error.invalid.name.id.header}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2. 给Controller类添加@Validated注解
@RequestHeader这类方法参数的校验,需要在Controller类上标注@Validated,否则Spring不会触发参数校验:
import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; @Validated @RestController public class PlanController { // 你的updatePlanProductByPlanId方法写在这里 }
3. 按预期方式使用注解
现在可以直接用@NameId替代重复的校验注解了:
public ResponseEntity<PlanResponse> updatePlanProductByPlanId( @RequestHeader(value = "name_id", required = true) @NameId String nameId, @PathVariable(value = "planid") @Valid @Pattern(regexp = REGEX_PATTERN_ONLY_NUMBERS, message = "{error.invalid.plan.id}") String planId, @Validated({OnPlanProductUpdate.class}) @RequestBody(required = true) SavePlanProductRequest updateProductRequest) throws ServiceException { // 方法业务逻辑 }
关键注意事项
- 不要在自定义注解上加
@Valid,它用于对象属性的级联校验,对字符串参数无效; - 自定义约束注解必须包含
message、groups、payload三个标准属性; - Controller类上的
@Validated是触发方法参数校验的必要前提。
内容的提问来源于stack exchange,提问作者theFlyingRaijin04
相关产品推荐
相关产品推荐

