@Constraint自定义参数校验注解

文章介绍了如何在Java项目中自定义注解以满足特定的参数校验需求,例如确保参数只能包含中文。通过创建自定义注解、注解校验类,以及在实体类、全局异常处理和Controller中应用这些注解,实现了对输入参数的有效控制。在Postman测试中,验证了自定义注解的效用。


前言

我们一般在项目中做参数校验都是使用@Vaild注解进行参数校验,但是官方提供的注解并不能全部满足我们的需求,所以就需要自定义注解对参数进行检验。下面就是使用@Constraint这个注解


一、需求

比如:我们对某个传入的参数要求只能是中文,不能是英文。

二、代码实现

1.自定义注解

代码如下(示例):

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解-只匹配中文
 */
@Target({ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {

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

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

    String message() default "校验参数通不过";
}

2.自定义注解校验类

需要实现ConstraintValidator接口,第一个参数为自定义注解类,第二个参数为要校验的参数类型

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 自定义注解校验类
 */
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {

    @Override
    public void initialize(MyConstraint constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        String pattern = "^[\\u4e00-\\u9fa5]{0,}$";
        Pattern p = Pattern.compile(pattern);
        Matcher matcher = p.matcher(value);
        while (matcher.find()) {
            return true;
        }
        return false;
    }
}

3.进行验证

3.1、定义实体类

import com.lbl.annotation.MyConstraint;
import lombok.Data;

import javax.validation.constraints.Email;

@Data
public class Student {

    @MyConstraint(message = "name字段只能为中文")
    private String name;

    private String address;

    @Email
    private String email;

    private String content;
}

3.2、全局异常处理

import com.lbl.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 全局异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String msg = null;
        if (bindingResult.hasErrors()) {
            List<ObjectError> errorList = e.getAllErrors();
            msg = errorList.get(0).getDefaultMessage();
            log.error("参数校验异常:{}", msg);
        }
        return Result.error(msg);
    }

}

3.3、controller测试

package com.lbl.controller;

import com.lbl.pojo.Student;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RequestMapping("/stu")
@RestController
public class StudentController {

    @PostMapping("/test")
    public String test(@RequestBody @Valid Student student) {
        return "Hello " + student.getName();
    }
}

3.4、postmant验证

输入非中文时
在这里插入图片描述


Spring 框架中,使用 `@Validated` 实现自定义注解以支持动态正则表达式参数校验是一种高级用法,适用于需要灵活校验规则的场景。以下是一个完整的实现方案。 ### 自定义注解的定义 首先,定义一个自定义注解 `@DynamicPattern`,其作用是允许在运行时动态传入正则表达式,以校验字符串类型的参数。 ```java import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = DynamicPatternValidator.class) public @interface DynamicPattern { String message() default "Invalid format"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } ``` ### 校验器实现 接下来,实现 `ConstraintValidator` 接口,编写具体的校验逻辑。通过从注解的属性中获取正则表达式,并在运行时动态校验输入值是否匹配。 ```java import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.regex.Pattern; public class DynamicPatternValidator implements ConstraintValidator<DynamicPattern, String> { private String regex; @Override public void initialize(DynamicPattern constraintAnnotation) { this.regex = constraintAnnotation.message(); // 假设 message 属性用于传递正则表达式 } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null) { return true; // 可根据需求定义 null 是否有效 } return Pattern.matches(regex, value); } } ``` ### 使用自定义注解 在业务实体或方法参数中使用 `@DynamicPattern` 注解,并通过 `message` 属性传递正则表达式。例如: ```java public class UserRequest { @DynamicPattern(message = "^[a-zA-Z0-9_]+$") // 动态指定正则表达式 private String username; // Getter and Setter } ``` ### 启用校验并处理异常 在 Spring Boot 应用中,确保在配置类或主类上使用 `@EnableValidation` 以启用校验功能。同时,可以通过 `@ExceptionHandler` 或 `@ControllerAdvice` 捕获校验异常并返回友好的错误信息。 ```java import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice public class ValidationExceptionHandler { @ExceptionHandler(javax.validation.ConstraintViolationException.class) public ResponseEntity<String> handleValidationExceptions() { return new ResponseEntity<>("Validation failed due to invalid input format.", HttpStatus.BAD_REQUEST); } } ``` ### 总结 通过自定义 `@DynamicPattern` 注解并结合 `ConstraintValidator` 的实现,可以实现基于动态正则表达式的参数校验功能。这种方式不仅灵活,还能够很好地与 Spring校验机制集成,适用于需要动态调整校验规则的业务场景[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值