欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java利用自定義注解實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)

 更新時(shí)間:2022年09月02日 15:31:54   作者:掃地和尚  
JSR303是一套JavaBean參數(shù)校驗(yàn)的標(biāo)準(zhǔn),它提供了一系列的校驗(yàn)方式,這些校驗(yàn)方式在javax.validation.constraints包中。本文就來聊聊如何利用它實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)

JSR303介紹

在Java中提供了一系列的校驗(yàn)方式

這些校驗(yàn)方式在javax.validation.constraints包中

引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

常用注解

@Null 驗(yàn)證對(duì)象是否為null 

@NotNull 驗(yàn)證對(duì)象是否不為null, 無法查檢長度為0的字符串 

@NotBlank 檢查約束字符串是不是Null還有被Trim的長度是否大于0,只對(duì)字符串,且會(huì)去掉前后空格. 

@NotEmpty 檢查約束元素是否為NULL或者是EMPTY.

Booelan檢查

  • @AssertTrue 驗(yàn)證 Boolean 對(duì)象是否為 true 
  • @AssertFalse 驗(yàn)證 Boolean 對(duì)象是否為 false

長度檢查

  • @Size(min=, max=) 驗(yàn)證對(duì)象(Array,Collection,Map,String)長度是否在給定的范圍之內(nèi) 
  • @Length(min=, max=) Validates that the annotated string is between min and max included.

日期檢查

  • @Past 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之前,驗(yàn)證成立的話被注釋的元素一定是一個(gè)過去的日期 
  • @Future 驗(yàn)證 Date 和 Calendar 對(duì)象是否在當(dāng)前時(shí)間之后 ,驗(yàn)證成立的話被注釋的元素一定是一個(gè)將來的日期 
  • @Pattern 驗(yàn)證 String 對(duì)象是否符合正則表達(dá)式的規(guī)則,被注釋的元素符合制定的正則表達(dá)式,regexp:正則表達(dá)式 flags: 指定 Pattern.Flag 的數(shù)組,表示正則表達(dá)式的相關(guān)選項(xiàng)。

數(shù)值檢查

建議使用在Stirng,Integer類型,不建議使用在int類型上,因?yàn)楸韱沃禐?ldquo;”時(shí)無法轉(zhuǎn)換為int,但可以轉(zhuǎn)換為Stirng為”“,Integer為null 

  • @Min 驗(yàn)證 Number 和 String 對(duì)象是否大等于指定的值 
  • @Max 驗(yàn)證 Number 和 String 對(duì)象是否小等于指定的值 
  • @DecimalMax 被標(biāo)注的值必須不大于約束中指定的最大值. 這個(gè)約束的參數(shù)是一個(gè)通過BigDecimal定義的最大值的字符串表示.小數(shù)存在精度 
  • @DecimalMin 被標(biāo)注的值必須不小于約束中指定的最小值. 這個(gè)約束的參數(shù)是一個(gè)通過BigDecimal定義的最小值的字符串表示.小數(shù)存在精度 
  • @Digits 驗(yàn)證 Number 和 String 的構(gòu)成是否合法 
  • @Digits(integer=,fraction=) 驗(yàn)證字符串是否是符合指定格式的數(shù)字,interger指定整數(shù)精度,fraction指定小數(shù)精度。 
  • @Range(min=, max=) 被指定的元素必須在合適的范圍內(nèi) 
  • @Range(min=10000,max=50000,message=”range.bean.wage”) 
  • @Valid 遞歸的對(duì)關(guān)聯(lián)對(duì)象進(jìn)行校驗(yàn), 如果關(guān)聯(lián)對(duì)象是個(gè)集合或者數(shù)組,那么對(duì)其中的元素進(jìn)行遞歸校驗(yàn),如果是一個(gè)map,則對(duì)其中的值部分進(jìn)行校驗(yàn).(是否進(jìn)行遞歸驗(yàn)證) 
  • @CreditCardNumber信用卡驗(yàn)證 
  • @Email 驗(yàn)證是否是郵件地址,如果為null,不進(jìn)行驗(yàn)證,算通過驗(yàn)證。 
  • @ScriptAssert(lang= ,script=, alias=) 
  • @URL(protocol=,host=, port=,regexp=, flags=)

開啟校驗(yàn)

controller中加校驗(yàn)注解@Valid,開啟校驗(yàn)

數(shù)據(jù)校驗(yàn)測試

步驟1:實(shí)體類字段上使用校驗(yàn)注解 @NotNull @NotEmpty @NotBlank @Pattern

步驟2:controller中加校驗(yàn)注解@Valid,開啟校驗(yàn)

步驟3:給校驗(yàn)的Bean后,緊跟一個(gè)BindingResult,就可以獲取到校驗(yàn)的結(jié)果

public R save(@Valid @RequestBody User user, BindingResult result){}

實(shí)體中添加注解

@Data
public class Student {
    @NotEmpty(message ="姓名不能為空")
    private String name;
}

controller層中保存方法添加:@Valid

   @PostMapping("/jsr")
    public AjaxResult testJrs(@Valid @RequestBody User user, BindingResult result) {
        String name = user.getName();
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("errors", result.getFieldErrors());
        return AjaxResult.success("數(shù)據(jù)校驗(yàn)", map);
    }

數(shù)據(jù)校驗(yàn)測試:測試:http://localhost:8080/test/jsr

@Data
public class User {

    @NotEmpty(message = "姓名不能為空")
    @ApiModelProperty("姓名")
    private String name;

    @ApiModelProperty("學(xué)號(hào)")
    private String id;

    @ApiModelProperty("年齡")
    private String age;
}

返回信息

{
  "msg": "數(shù)據(jù)校驗(yàn)",
  "code": 200,
  "data": {
    "name": "",
    "errors": [
      {
        "codes": [
          "NotEmpty.user.name",
          "NotEmpty.name",
          "NotEmpty.java.lang.String",
          "NotEmpty"
        ],
        "arguments": [
          {
            "codes": [
              "user.name",
              "name"
            ],
            "defaultMessage": "name",
            "code": "name"
          }
        ],
        "defaultMessage": "姓名不能為空",
        "objectName": "user",
        "field": "name",
        "rejectedValue": "",
        "bindingFailure": false,
        "code": "NotEmpty"
      }
    ]
  }
}

自定義的封裝錯(cuò)誤信息

    @PostMapping("/package")
    public AjaxResult testPackage(@Valid @RequestBody User user, BindingResult result) {
        String name = user.getName();
        Map<String, String> map = new HashMap<>();
        map.put("name", name);
        if (result.hasErrors()) {
            //1.獲取錯(cuò)誤的校驗(yàn)結(jié)果
            result.getFieldErrors().forEach((item) -> {
                //2.獲取發(fā)生錯(cuò)誤時(shí)的message
                String message = item.getDefaultMessage();
                //3.獲取發(fā)生錯(cuò)誤的字段
                String field = item.getField();
                map.put(field, message);
            });
            return AjaxResult.error("數(shù)據(jù)校驗(yàn)", map);
        } else {
            return AjaxResult.success(map);
        }
    }

自定義的封裝錯(cuò)誤信息:測試:http://localhost:80/test/package

{
  "name": "",
  "id": "demoData",
  "age": "demoData"
}

錯(cuò)誤信息

{
  "msg": "數(shù)據(jù)校驗(yàn)",
  "code": 500,
  "data": {
    "name": "姓名不能為空"
  }
}

統(tǒng)一異常處理

@Slf4j
@RestControllerAdvice(basePackages = "com.michale.jrs303.controllers")
public class FireflyMallExceptionControllerAdvice {
    /**
     * 處理數(shù)據(jù)校驗(yàn)問題
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handleVaildException(MethodArgumentNotValidException e) {
        log.error("數(shù)據(jù)校驗(yàn)出現(xiàn)問題:{},異常類型:{}", 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 Result.fail(errorMap, "數(shù)據(jù)校驗(yàn)出現(xiàn)問題");
    }

    /**
     * 處理其他異常
     * @param throwable
     * @return
     */
    @ExceptionHandler(value = Throwable.class)
    public Result handleException(Throwable throwable) {
        return Result.fail();
    }
}
    @RequestMapping("/testException")
    public Result testException(@Valid @RequestBody Student student) {
        String name = student.getName();
        Map<String, String> map = new HashMap<>();
        map.put("name", name);
        return Result.ok(map);
    }

測試統(tǒng)一異常處理:測試:http://localhost:8080/testException

{
  "msg": "數(shù)據(jù)校驗(yàn)出現(xiàn)問題",
  "path": "/test/testException",
  "code": 414,
  "errors": {
    "name": "姓名不能為空"
  }
}

錯(cuò)誤信息

{
	"code": 500,
	"msg": "數(shù)據(jù)校驗(yàn)出現(xiàn)問題",
	"data": {
		"name": "姓名不能為空"
	}
}

分組校驗(yàn)

創(chuàng)建分組校驗(yàn)接口

/**
 * @Author 天才小狐貍
 * @Data 2022/8/11 2:03
 * @Description 姓名校驗(yàn)分組
 */
public interface NameGroup {
}
/**
 * @Author 天才小狐貍
 * @Data 2022/8/11 2:04
 * @Description 年齡校驗(yàn)分組
 */
public interface AgeGroup {
}

添加校驗(yàn)注解

@Data
public class Student {
    @NotEmpty(message ="姓名不能為空",groups =  NameGroup.class)
    private String name;

    @NotEmpty(message ="綽號(hào)不能為空",groups = NameGroup.class)
    private  String nickName;

    @Min(value = 18,message = "年齡下限不能低于18歲" ,groups = AgeGroup.class)
    private String age;

    @Max(value = 60,message = "年齡上限不能超過60歲" ,groups = AgeGroup.class)
    private  String retireAge;
}

開啟分組校驗(yàn)

@Validated(NameGroup.class)指定校驗(yàn)分組

@RequestMapping("/testGroup")
    public Result testGroup(@Validated(NameGroup.class) @RequestBody Student student) {
        String name = student.getName();
        String nickName = student.getNickName();
        String age = student.getAge();
        String retireAge = student.getRetireAge();
        Map<String, String> map = new HashMap<>();
        map.put("name", name);
        map.put("nickname", nickName);
        map.put("age", age);
        map.put("retireAge", retireAge);
        return Result.ok(map);
    }

測試分組校驗(yàn):http://localhost:8080/testGroup

{
    "name":"",
    "nickName":"",
    "age":"17",
    "retireAge":"66"
}

錯(cuò)誤信息

{
	"code": 500,
	"msg": "數(shù)據(jù)校驗(yàn)出現(xiàn)問題",
	"data": {
		"nickName": "綽號(hào)不能為空",
		"name": "姓名不能為空"
	}
}

@Validated(AgeGroup.class)指定校驗(yàn)分組

@RequestMapping("/testGroup")
    public Result testGroup(@Validated(AgeGroup.class) @RequestBody Student student) {
        String name = student.getName();
        String nickName = student.getNickName();
        String age = student.getAge();
        String retireAge = student.getRetireAge();
        Map<String, String> map = new HashMap<>();
        map.put("name", name);
        map.put("nickname", nickName);
        map.put("age", age);
        map.put("retireAge", retireAge);
        return Result.ok(map);
    }

測試分組校驗(yàn):http://localhost:8080/testGroup

{
    "name":"",
    "nickName":"",
    "age":"17",
    "retireAge":66
}

錯(cuò)誤信息

{
	"code": 500,
	"msg": "數(shù)據(jù)校驗(yàn)出現(xiàn)問題",
	"data": {
		"retireAge": "年齡上限不能超過60歲",
		"age": "年齡下限不能低于18歲"
	}
}

自定義校驗(yàn)

編寫自定義的校驗(yàn)注解

比如要?jiǎng)?chuàng)建一個(gè):@ListValue 注解,被標(biāo)注的字段值只能是:0或1

@Documented
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
    // 使用該屬性去Validation.properties中取
    String message() default "{com.atguigu.common.valid.ListValue.message}";

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

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

    int[] value() default {};
}

設(shè)置錯(cuò)誤信息:創(chuàng)建文件ValidationMessages.properties

 com.firefly.common.valid.ListValue.message=必須提交指定的值 [0,1]

編寫自定義的校驗(yàn)器

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

/**
 * @author Michale @EMail:firefly@163.com
 * @Date: 2022/1/8 19:23
 * @Name ListValueConstraintValidator
 * @Description:
 */
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) {
        //判斷傳入的值是否在滿足允許的值
        boolean b = set.contains(value);
        return b;
    }
}

關(guān)聯(lián)校驗(yàn)器和校驗(yàn)注解

在@ListValue注解關(guān)聯(lián)校驗(yàn)器

@Constraint(validatedBy = { ListValueConstraintValidator.class})

一個(gè)校驗(yàn)注解可以匹配多個(gè)校驗(yàn)器

添加自定義的校驗(yàn)注解

    @ListValue(value = {0,1},groups = {AgeGroup.class,MyJRS303Group.class})
    private Integer gender;

測試自定義校驗(yàn)器:http://localhost:8080/testGroup

{
    "gender":"3"
}
{
	"code": 500,
	"msg": "數(shù)據(jù)校驗(yàn)出現(xiàn)問題",
	"data": {
		"gender": "必須提交指定的值 [0,1]"
	}
}

以上就是Java利用自定義注解實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于Java數(shù)據(jù)校驗(yàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

 

相關(guān)文章

最新評(píng)論