JSR303校验注解和自定义校验注解的使用

引入validation依赖

 <!--JSR303依赖 -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-validation</artifactId>
 </dependency>

Null检查
@Null(message = "")       验证对象是否为null
@NotNull(message = "")    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank(message = "")   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty(message = "")  检查约束元素是否为NULL或者是EMPTY.

Booelan检查
@AssertTrue(message = "")     验证 Boolean 对象是否为 true 
@AssertFalse(message = "")    验证 Boolean 对象是否为 false

长度检查
@Size(min=, max=,message = "") 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内 
@Length(min=, max=,message = "") Validates that the annotated string is between min and max included.

日期检查
@Past(message = "")           验证 Date 和 Calendar 对象是否在当前时间之前 
@Future(message = "")      验证 Date 和 Calendar 对象是否在当前时间之后 
@Pattern(regexp = "",message = "")     验证 String 对象是否符合正则表达式的规则

数值检查

建议使用在包装类型(Integer这类),不建议使用在int类型上,
 因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
@Min(message = "")     验证 Number 和 String 对象是否大等于指定的值 
@Max(message = "")     验证 Number 和 String 对象是否小等于指定的值 
@DecimalMax(message = "") 值不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin(message = "") 值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits(message = "")     验证 Number 和 String 的构成是否合法 
@Digits(integer=,fraction=,message = "") 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=,message = "") 检查数字是否介于min和max之间.
@Valid  递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber(message = "") 信用卡验证
@Email(message = "")  验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=,message = "")
@URL(protocol=,host=, port=,regexp=, flags=,message = "")

每一个校验注解都有一个message用来定义错误信息的返回信息,也有一个groups用来定义不同情形写生效的注解,需要传入一个接口类型的类用来定义。

在进行分组校验的情况下,没有携带groups的校验注解不生效,不是一组的也不会生效,使用方式先在要校验的字段标记注解并且填入groups=接口名.class需要编写一个空接口用来标记分组

不分组校验的情况下不标记groups的注解也会生效

在springboot中使用@Validated(value = {接口名.class})来指定那个groups生效

自定义校验可以使用@Pattern 输入正则表达式,会根据正则校验

在实体中添加校验注解

前端将数据提交给后端的controller、controller通过映射将数据映射到实体,在映射的时候会进行校验,如果校验不通过会通过message填入的信息将错误信息返回给controller中对于的方法

在实体层添加注解,其中message是返回的消息

public class Person {
 @NotEmpty(message="姓名不能为空")
 private String name;

 private int userId;

 @Length(min=6,max=10,message="密码必须在6-10位之间")
 private String password;

 @Email(message="邮箱不符合格式")
 private String email;
}

开启校验

在入请求体参数加上@Valid注解

在springboot中使用@Validated注解,是JSR303规范中springboot的实现

@PostMapping("/person")
public Object addPerson(@RequestBody @Valid Person person, BindingResult result) {
 if (result.hasErrors()) { // 判断异常,将异常返回
 List<ObjectError> allErrors = result.getAllErrors(); //获取所有的异常信息
 for (ObjectError error : allErrors) {
  System.out.println(error.getCode() + "\t"
   + error.getDefaultMessage());
 }
 }
 return person;
}

集中处理异常示例代码

import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * 集中处理所有异常
 */
@Slf4j
@RestControllerAdvice(basePackages = "抛异常的类全路径")
public class GulimallExceptionControllerAdvice {

  @ExceptionHandler(value= MethodArgumentNotValidException.class)
  public R handleVaildException(MethodArgumentNotValidException e){
    log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
    BindingResult bindingResult = e.getBindingResult();

    Map<String,String> errorMap = new HashMap<>();
    bindingResult.getFieldErrors().forEach((fieldError)->{
      errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
    });
    return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
  }

  @ExceptionHandler(value = Throwable.class)
  public R handleException(Throwable throwable){

    log.error("错误:",throwable);
    return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
  }
}

自定义校验注解

自定义校验注解必须要有三个内容values,message,groups

也就是必须要哟下面的3行代码

String message() default "{com.atguigu.common.valid.ListValue.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };

message中{com.atguigu.common.valid.ListValue.message}是默认的返回错误信息

因此需要创建对应的properties/yml文件,并且在其中定义错误信息的值

例如 com.atguigu.common.valid.ListValue.message=必须提交指定的值!

同时需要下面这些注解@Target指定注解在那些地方生效,METHOD表示方法、FIELD表示字段其他的类推
@Constraint用来指定自定义校验的校验器,validatedBy = { ListValueConstraintValidator.class }表示指定ListValueConstraintValidator.class作为校验器,可以有多个

@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)

如果找不到类则添加依赖

<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
  <groupId>javax.validation</groupId>
  <artifactId>validation-api</artifactId>
  <version>2.0.1.Final</version>
</dependency>

完整的自定义校验注解的案例

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

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

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

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

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

  int[] vals() default { };
}

使用案例

groups指定分组生效

@ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
private Integer showStatus;

要使校验注解生效,需要有一个自定义的校验注解器,实现ConstraintValidator接口需要有两个泛型

第一个是注解类,另一个是校验值的类型

例如

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {

  private Set<Integer> set = new HashSet<>();
  //初始化方法
  @Override
  public void initialize(ListValue constraintAnnotation) {

    int[] vals = constraintAnnotation.vals();
    for (int val : vals) {
      set.add(val);
    }

  }

  //判断是否校验成功

  /**
   *
   * @param value 需要校验的值
   * @param context
   * @return
   */
  @Override
  public boolean isValid(Integer value, ConstraintValidatorContext context) {

    return set.contains(value);
  }
}

进行校验的类,其中BrandEntity 中有上面的showStatus字段并且有对应的自定义校验注解

  @RequestMapping("/update")
  public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
 /*业务代码*/
    return R.ok();
  }

到此这篇关于JSR303校验注解和自定义校验注解的使用的文章就介绍到这了,更多相关JSR303校验注解内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot集成JSR303参数校验的方法实现

    JSR303 是一套 JavaBean 参数校验的标准 1.pom导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 2.注解类型 (1)空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null,

  • Java如何使用JSR303校验数据与自定义校验注解

    一.自带校验注解实现数据校验 1.web项目导入依赖 <!-- 该依赖默认导入了 hibernate-validator 所以不需要再单独导入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 下图可以看到spring-boot

  • JSR303校验注解和自定义校验注解的使用

    引入validation依赖 <!--JSR303依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> Null检查 @Null(message = "")       验证对象是否为null

  • Hibernate validator使用以及自定义校验器注解

    JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,用于对 Java Bean 中的字段的值进行验证.Hibernate Validator则是Hibdernate提供的一种对该规范的实现. --即Hibernate Validator是用来做参数校验. 使用Hibernate Validator提供的注解进行参数校验 注解 释义 @Null 必须为null @NotNull 不能为null @AssertTrue 必须为true @AssertFals

  • Spring的@Validation和javax包下的@Valid区别以及自定义校验注解

    1.后台参数校验 Spring Validation验证框架对参数的验证机制提供了@Validated(Spring JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果 spring提供的验证:org.springframework.validation.annotation.Validated; javax提供的验证:javax.validation.Valid; 在检验Contr

  • 浅谈自定义校验注解ConstraintValidator

    目录 一.前言 二.自定义参数校验器 三.使用自定义注解 一.前言 系统执行业务逻辑之前,会对输入数据进行校验,检测数据是否有效合法的.所以我们可能会写大量的if else等判断逻辑,特别是在不同方法出现相同的数据时,校验的逻辑代码会反复出现,导致代码冗余,阅读性和可维护性极差. JSR-303是Java为Bean数据合法性校验提供的标准框架,它定义了一整套校验注解,可以标注在成员变量,属性方法等之上. hibernate-validator就提供了这套标准的实现,我们在用Springboot开

  • SpringBoot自定义注解实现Token校验的方法

    1.定义Token的注解,需要Token校验的接口,方法上加上此注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementTyp

  • 基于自定义校验注解(controller、method、(groups)分组的使用)

    目录 1.首先创建两个自定义校验注解类 2.校验注解的使用 1>.controller中的使用 2>.方法中触发注解 3>.分组groups的使用 单个注解用在方法上(@Validated--以异常形式抛出) 1.实例化MethodValidationPostProcessor 2.在所要实现方法参数校验的类上面添加@Validated 3.在方法上面添加校验规则 1.首先创建两个自定义校验注解类 package com.example.demo.annotation; import c

  • SpringBoot常见get/post请求参数处理、参数注解校验及参数自定义注解校验详解

    目录 springboot常见httpget,post请求参数处理 PathVaribale获取url路径的数据 RequestParam获取请求参数的值 注意 GET参数校验 POSTJSON参数校验 自定义注解校验 总结 spring boot 常见http get ,post请求参数处理 在定义一个Rest接口时通常会利用GET.POST.PUT.DELETE来实现数据的增删改查:这几种方式有的需要传递参数,后台开发人员必须对接收到的参数进行参数验证来确保程序的健壮性 GET一般用于查询数

  • SpringBoot通过自定义注解实现参数校验

    目录 1. 为什么要进行参数校验 2. 如何实现参数校验 3. 注解实现参数校验 4. 自定义注解实现参数校验 1. 为什么要进行参数校验 在后端进行工作时,需要接收前端传来的数据去数据库查询,但是如果有些数据过于离谱,我们就可以直接把它pass掉,不让这种垃圾数据接触数据库,减小数据库的压力. 有时候会有不安分的人通过一些垃圾数据攻击咱们的程序,让咱们的服务器或数据库崩溃,这种攻击虽然低级但不得不防,就像QQ进行登录请求时,它们向后端发送 账号=123,密码=123 的数据,一秒钟还发1w次,

  • 详解在Spring MVC中使用注解的方式校验RequestParams

    概述 Spring MVC支持Bean Validation,通过这个验证技术,可以通过注解方式,很方便的对输入参数进行验证,之前使用的校验方式,都是基于Bean对象的,但是在@RequestParam中,没有Bean对象,这样使得校验无法进行,可以通过使用@Validated注解,使得校验可以进行. 校验bean对象 一般校验bean对象,为了可以自动的校验属性,可以通过两步解决: 一.声明对象 package com.github.yongzhizhan.draftbox.model; im

随机推荐