springboot获取payload_springboot自定义注解-注解校验,让代码更简洁
Java注解简介:Java注解又称Java标注,是JDK5.0版本开始支持加入源代码的特殊语法元数据。Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java虚拟机可以保留标注内容,在运行时可以获取到标注内容。 当然它也支持自定义Java标注。java元注解所在包java.lang.
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 = 只能为falsejavax.validation.constraints.AssertTrue.message = 只能为truejavax.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 = 不能为nulljavax.validation.constraints.Null.message = 必须为nulljavax.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 = 需要是一个合法的URLorg.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 { private Set 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 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}+$",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)测试
更多推荐
所有评论(0)