1. 程式人生 > 實用技巧 >springboot整合validation統一引數檢查

springboot整合validation統一引數檢查

1.背景

實際開發中對引數進行檢查,是常見

比如如下程式碼

/**
     * 引數檢查測試(傳統做法)
     *
     * @param dto
     * @return
     */
    @GetMapping("/paramCheckOld")
    public BaseResponse paramCheckOld(@RequestBody UserDTO dto) {
        // 引數檢查
        if (StrUtil.isEmpty(dto.getWeChat())) {
            return ResponseBuilder.failed("微訊號為空");
        }
        
if (StrUtil.isEmpty(dto.getName())) { return ResponseBuilder.failed("姓名為空"); } if (dto.getStatus() != null || dto.getStatus() != -1 || dto.getStatus() != 0 || dto.getStatus() != 1) { return ResponseBuilder.failed("狀態為-1,0,1或者null"); }
// .....如果引數很多這裡必然後崩潰.......... // 呼叫業務方法 // 響應結果 System.out.println("dto=" + dto); return ResponseBuilder.success("統一引數檢查....."); }

但是正確的做法應該是,這裡其實只使用了一個@Validated註解就搞定了,太方便了.....

 /**
     * 統一引數檢查(牛逼的做法)
     *
     * @param dto
     * @return
     */
    @GetMapping(
"/paramCheck") public BaseResponse paramCheck(@RequestBody @Validated UserDTO dto) { // 引數檢查(已檢查) // 呼叫業務方法 // 響應結果 System.out.println("dto=" + dto); return ResponseBuilder.success("統一引數檢查....."); }

2.步驟

步驟一:引入jar包

 <!--  統一引數校驗-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

步驟二:引數上貼標籤

package com.ldp.user.entity.dto;

import com.ldp.user.common.validation.EnumValue;
import lombok.Data;

import javax.validation.constraints.NotBlank;

/**
 * @author 姿勢帝-部落格園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 01/01 4:00
 * @description
 */
@Data
public class UserDTO {
    @NotBlank(message = "微訊號不能為空")
    private String weChat;

    @NotBlank(message = "姓名不能為空")
    private String name;
    /**
     * 年齡
     */
    private Integer age;
    /**
     * 狀態
     * -1:凍結使用者 ,0:正常使用者, 1:沒有實名認證
     */
    @EnumValue(intValues = {-1, 0, 1}, message = "狀態為-1,0,1或者null")
    private Integer status;
    /**
     * 地址
     */
    private String address;
}

步驟三:控制層方法上貼標籤(當然在其他方法上也可以用的,只是一般我們用在控制層上)

/**
     * 統一引數檢查(牛逼的做法)
     *
     * @param dto
     * @return
     */
    @GetMapping("/paramCheck")
    public BaseResponse paramCheck(@RequestBody @Validated UserDTO dto) {
        // 引數檢查(已檢查)
        // 呼叫業務方法
        // 響應結果
        System.out.println("dto=" + dto);
        return ResponseBuilder.success("統一引數檢查.....");
    }

步驟四:統一引數檢查不通過時提示訊息獲取

  /**
     * 引數異常捕獲
     *
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public Object constraintViolationExceptionHandler(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
        List<String> msgList = new ArrayList<>();
        while (iterator.hasNext()) {
            ConstraintViolation<?> cvl = iterator.next();
            msgList.add(cvl.getMessageTemplate());
        }
        return ResponseBuilder.failed(msgList.toString());
    }

    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Object getBindException(BindException ex) {
        List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
        if (!CollectionUtils.isEmpty(objectErrors)) {
            StringBuilder msgBuilder = new StringBuilder();
            for (ObjectError objectError : objectErrors) {
                msgBuilder.append(objectError.getDefaultMessage()).append(",");
            }
            String errorMessage = msgBuilder.toString();
            if (errorMessage.length() > 1) {
                errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
            }
            return ResponseBuilder.failed(errorMessage);
        }
        return ResponseBuilder.failed(ex.getMessage());
    }

步驟五測試

  @Test
    void paramCheck() {
        String url = urlLocal + "/userOrder/paramCheck";
        System.out.println("請求地址:" + url);
        HttpRequest request = HttpUtil.createRequest(Method.GET, url);
        Map<String, Object> map = new TreeMap<>();
        // 業務引數
      //  map.put("weChat", "851298348");
       // map.put("name", "李東平");
        map.put("age", "18");
        map.put("status", "0");
        map.put("address", "四川成都");

        // 公用引數
        map.put("appid", "1001");
        map.put("sequenceId", "seq" + System.currentTimeMillis());
        map.put("timeStamp", System.currentTimeMillis());
        map.put("sign", signApi(map, "123456"));
        String param = JSON.toJSONString(map);
        request.body(param);
        System.out.println("請求引數:" + param);
        request.header("Authorization", token);
        request.setConnectionTimeout(60 * 1000);
        String response = request.execute().body();
        System.out.println("請求結果:" + response);
    }

測試結果:

{"message":"微訊號不能為空,姓名不能為空","code":900}

3.常用檢查規則註解

JSR提供的校驗註解:         
@Null   被註釋的元素必須為 null    
@NotNull    被註釋的元素必須不為 null    
@AssertTrue     被註釋的元素必須為 true    
@AssertFalse    被註釋的元素必須為 false    
@Min(value)     被註釋的元素必須是一個數字,其值必須大於等於指定的最小值    
@Max(value)     被註釋的元素必須是一個數字,其值必須小於等於指定的最大值    
@DecimalMin(value)  被註釋的元素必須是一個數字,其值必須大於等於指定的最小值    
@DecimalMax(value)  被註釋的元素必須是一個數字,其值必須小於等於指定的最大值    
@Size(max=, min=)   被註釋的元素的大小必須在指定的範圍內    
@Digits (integer, fraction)     被註釋的元素必須是一個數字,其值必須在可接受的範圍內    
@Past   被註釋的元素必須是一個過去的日期    
@Future     被註釋的元素必須是一個將來的日期    
@Pattern(regex=,flag=)  被註釋的元素必須符合指定的正則表示式    


Hibernate Validator提供的校驗註解:  
@NotBlank(message =)   驗證字串非null,且trim後長度必須大於0    
@Email  被註釋的元素必須是電子郵箱地址    
@Length(min=,max=)  被註釋的字串的大小必須在指定的範圍內    
@NotEmpty   被註釋的字串的必須非空    
@Range(min=,max=,message=)  被註釋的元素必須在合適的範圍內

4.自定義檢查規則註解

如果這些註解還不能滿足我們的需求,那麼我麼可以自己定義滿足自己業務規則的註解

這裡以自定義一個列舉值檢查的註解,這個在實際生產中用的非常普遍

比如在傳入使用者狀態時,只嗯傳入-1,0,1或者null,其都是引數不合法的檢查註解

https://www.cnblogs.com/newAndHui/p/14185807.html

完美!