JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

springboot自定义注解-注解校验,让代码更简洁

wys521 2024-12-04 14:29:00 精选教程 22 ℃ 0 评论

Java注解简介:

Java注解又称Java标注,是JDK5.0版本开始支持加入源代码的特殊语法元数据。

Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java虚拟机可以保留标注内容,在运行时可以获取到标注内容。 当然它也支持自定义Java标注。

java元注解所在包java.lang.annotation,下面有很多元注解【如下图】:


jakarta-validation和hibernate-validation为我们提供了很多拿来即用的校验注解

引入springboot相关pom坐标就会自动给我们引入对应的jakarta-validation和hibernate-validation包



jakarta-validation和hibernate-validation中常用注解说明:

javax.validation.constraints.AssertFalse.message     = 只能为false
javax.validation.constraints.AssertTrue.message      = 只能为true
javax.validation.constraints.DecimalMax.message      = 必须小于或等于{value}
javax.validation.constraints.DecimalMin.message      = 必须大于或等于{value}
javax.validation.constraints.Digits.message          = 数字的值超出了允许范围(只允许在{integer}位整数和{fraction}位小数范围内)
javax.validation.constraints.Email.message           = 不是一个合法的电子邮件地址
javax.validation.constraints.Future.message          = 需要是一个将来的时间
javax.validation.constraints.FutureOrPresent.message = 需要是一个将来或现在的时间
javax.validation.constraints.Max.message             = 最大不能超过{value}
javax.validation.constraints.Min.message             = 最小不能小于{value}
javax.validation.constraints.Negative.message        = 必须是负数
javax.validation.constraints.NegativeOrZero.message  = 必须是负数或零
javax.validation.constraints.NotBlank.message        = 不能为空
javax.validation.constraints.NotEmpty.message        = 不能为空
javax.validation.constraints.NotNull.message         = 不能为null
javax.validation.constraints.Null.message            = 必须为null
javax.validation.constraints.Past.message            = 需要是一个过去的时间
javax.validation.constraints.PastOrPresent.message   = 需要是一个过去或现在的时间
javax.validation.constraints.Pattern.message         = 需要匹配正则表达式"{regexp}"
javax.validation.constraints.Positive.message        = 必须是正数
javax.validation.constraints.PositiveOrZero.message  = 必须是正数或零
javax.validation.constraints.Size.message            = 个数必须在{min}和{max}之间

org.hibernate.validator.constraints.CreditCardNumber.message        = 不合法的信用卡号码
org.hibernate.validator.constraints.Currency.message                = 不合法的货币 (必须是{value}其中之一)
org.hibernate.validator.constraints.EAN.message                     = 不合法的{type}条形码
org.hibernate.validator.constraints.Email.message                   = 不是一个合法的电子邮件地址
org.hibernate.validator.constraints.Length.message                  = 长度需要在{min}和{max}之间
org.hibernate.validator.constraints.CodePointLength.message         = 长度需要在{min}和{max}之间
org.hibernate.validator.constraints.LuhnCheck.message               = ${validatedValue}的校验码不合法, Luhn模10校验和不匹配
org.hibernate.validator.constraints.Mod10Check.message              = ${validatedValue}的校验码不合法, 模10校验和不匹配
org.hibernate.validator.constraints.Mod11Check.message              = ${validatedValue}的校验码不合法, 模11校验和不匹配
org.hibernate.validator.constraints.ModCheck.message                = ${validatedValue}的校验码不合法, ${modType}校验和不匹配
org.hibernate.validator.constraints.NotBlank.message                = 不能为空
org.hibernate.validator.constraints.NotEmpty.message                = 不能为空
org.hibernate.validator.constraints.ParametersScriptAssert.message  = 执行脚本表达式"{script}"没有返回期望结果
org.hibernate.validator.constraints.Range.message                   = 需要在{min}和{max}之间
org.hibernate.validator.constraints.SafeHtml.message                = 可能有不安全的HTML内容
org.hibernate.validator.constraints.ScriptAssert.message            = 执行脚本表达式"{script}"没有返回期望结果
org.hibernate.validator.constraints.URL.message                     = 需要是一个合法的URL

org.hibernate.validator.constraints.time.DurationMax.message        = 必须小于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小时'}${minutes == 0 ? '' : minutes += '分钟'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '纳秒'}
org.hibernate.validator.constraints.time.DurationMin.message        = 必须大于${inclusive == true ? '或等于' : ''}${days == 0 ? '' : days += '天'}${hours == 0 ? '' : hours += '小时'}${minutes == 0 ? '' : minutes += '分钟'}${seconds == 0 ? '' : seconds += '秒'}${millis == 0 ? '' : millis += '毫秒'}${nanos == 0 ? '' : nanos += '纳秒'}

重点:自定义注解校验

当官方提供的注解不够满足不了我们实际开发需求时,我们就可以自己定义符合自己业务逻辑的注解。

下面我们来自定义一个校验集合内容的注解,要求:只允许输入注解传递的值

1)创建ListValue.java注解类

@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {
    String message() default "{com.bigdata.common.valid.ListValue.message}";

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

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

    int[] value() default {};
}

ListValueConstraintValidator.class是我们的校验器,用于书写我们校验的业务逻辑

2)创建ListValueConstraintValidator.java校验器类

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
    private Set<Integer> set=new HashSet<>();
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] value = constraintAnnotation.value();
        for (int i : value) {
            set.add(i);
        }

    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {


        return  set.contains(value);
    }

}

3)统一异常处理类,用于处理参数校验异常

@Slf4j
@RestControllerAdvice(basePackages = "com.bigcat.gulimall.gulimallproduct.controller" )
public class ExceptionAdvice {
    /**
     * 未知异常
     * @param throwable
     * @return
     */
    @ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable){
        log.error("未知异常{},异常类型{}",throwable.getMessage(),throwable.getClass());
        return R.error(1000,"未知异常");
    }

    /**
     * 数据校验异常
     * @param exception
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException exception){
        Map<String,String> map=new HashMap<>();
        BindingResult bindingResult = exception.getBindingResult();
        bindingResult.getFieldErrors().forEach(fieldError -> {
            String message = fieldError.getDefaultMessage();
            String field = fieldError.getField();
            map.put(field,message);
        });

        log.error("数据校验出现问题{},异常类型{}",exception.getMessage(),exception.getClass());
        return R.error(1234,"参数校验异常").put("data",map);
    }





}

4)使用我们自定义的注解来校验我们我们需要校验的字段showStatus,顺便使用一下Jakarta-validation里的注解

@Data
@TableName()
public class BrandEntity implements Serializable {
   private static final long serialVersionUID = 1L;

   /**
    * 品牌id
    */
   @TableId
   @NotNull(message = "不能为null",groups = {UpdateGroup.class})
   private Long brandId;
   /**
    * 品牌名
    */
   @NotBlank(message = "品牌名必须非空",groups = {AddGroup.class})
   private String name;
   /**
    * 品牌logo地址
    */
   @NotBlank(message = "logo不能为空",groups = {AddGroup.class})
   @URL(message = "logo必须为一个合法的url")
   private String logo;
   /**
    * 介绍
    */
   private String descript;
   /**
    * 显示状态[0-不显示;1-显示]
    */
   @NotNull(message = "显示状态不能为Null",groups = {AddGroup.class})
// @Min(value = 0,message = "必须为0或者1",groups = {AddGroup.class,UpdateGroup.class})
// @Max(value = 1,message = "必须为0或者1",groups = {AddGroup.class,UpdateGroup.class})
   @ListValue(value = {0,1},message = "必须为0或者1",groups = {AddGroup.class,UpdateGroup.class})
   private Integer showStatus;
   /**
    * 检索首字母
    */
   @NotBlank(message = "检索首字母不能为空",groups = {AddGroup.class})
   @Pattern(regexp = "^[A-Za-z]{1}+#34;,message = "检索首字母必须为一个字母",groups = {AddGroup.class,UpdateGroup.class})
   private String firstLetter;
   /**
    * 排序
    */
   @NotNull(message = "不能为空",groups = {AddGroup.class})
   @Min(value = 0)
   private Integer sort;

}

5)在接口中java注解@Validated,不然不会生效

@RequestMapping("/save")
  public R save(@Validated(value = AddGroup.class) @RequestBody BrandEntity brand){
brandService.save(brand);

      return R.ok();
  }

6)测试


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表