SpringBoot 校驗post請求參數


導讀

  前后端分離項目中,前端往后端傳值時,后端都要做參數格式校驗,比如校驗數字最大值、最小值、是否允許為空、日期格式等等。

添加依賴

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

自定義日期注解

作用

  校驗日期格式,自定義校驗規格

DateTime.java

package net.ybclass.online_ybclass.utils;

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

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateTimeValidator.class)
public @interface DateTime {
    String message() default "日期格式錯誤";

    String format() default "yyyyMM";

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

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

約束自定義注解校驗器

作用

  校驗自定義注解驗證格式

DateTimeValidator.java

package net.ybclass.online_ybclass.utils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.SimpleDateFormat;

/**
 * @ClassName:DateTimeValidator
 * @Description:日期校驗器
 * @Author:chenyb
 * @Date:2020/11/17 10:13 上午
 * @Versiion:1.0
 */
public class DateTimeValidator implements ConstraintValidator<DateTime, String> {
    private DateTime dateTime;

    /**
     * 初始化
     * @param dateTime
     */
    @Override
    public void initialize(DateTime dateTime) {
        this.dateTime = dateTime;
    }

    /**
     * 驗證參數
     * @param value
     * @param context
     * @return
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 如果 value 為空則不進行格式驗證,為空驗證可以使用 @NotBlank @NotNull @NotEmpty 等注解來進行控制,職責分離
        if (value == null) {
            return true;
        }
        String format = dateTime.format();

        if (value.length() != format.length()) {
            return false;
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);

        try {
            simpleDateFormat.parse(value);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
}

常用校驗注解標簽

  • @AssertFalse 所注解的元素必須是Boolean類型,且值為false
  • @AssertTrue 所注解的元素必須是Boolean類型,且值為true
  • @DecimalMax 所注解的元素必須是數字,且值小於等於給定的值
  • @DecimalMin 所注解的元素必須是數字,且值大於等於給定的值
  • @Digits 所注解的元素必須是數字,且值必須是指定的位數
  • @Future 所注解的元素必須是將來某個日期
  • @Max 所注解的元素必須是數字,且值小於等於給定的值
  • @Min 所注解的元素必須是數字,且值小於等於給定的值
  • @Range 所注解的元素需在指定范圍區間內
  • @NotNull 所注解的元素值不能為null
  • @NotBlank 所注解的元素值有內容
  • @Null 所注解的元素值為null
  • @Past 所注解的元素必須是某個過去的日期
  • @PastOrPresent 所注解的元素必須是過去某個或現在日期
  • @Pattern 所注解的元素必須滿足給定的正則表達式
  • @Size 所注解的元素必須是String、集合或數組,且長度大小需保證在給定范圍之內
  • @Email 所注解的元素需滿足Email格式

demo

請求參數實體類

package net.ybclass.online_ybclass.model.request;

import net.ybclass.online_ybclass.utils.DateTime;

import javax.validation.constraints.*;

public class ParamValidRequest {
    @Max(value = 100, message = "id=最大值不能超過100")
    @Min(value = 1, message = "id=最小不能小於1")
    private int id;
    @NotNull(message = "userName======》@NotNull")
    private String userName;
    @NotBlank(message = "salary======》@NotBlank")
    private String salary;
    @NotBlank
    @Pattern(regexp = "1234567890",message = "phone=手機號支持正則表達式,手機號必須:1234567890")
    private String phone;
    //刪除時間,當輸入的時間為2020-08-26或2020/08/26 11:22:33,時間格式不符合"yyyy-MM-dd HH:mm:ss"
    //@Pattern(regexp = "^((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))\\s+([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$")
    @NotNull
    @DateTime(format = "yyyy-MM-dd",message = "createDate=日期格式不正確,正確格式:yyyy-MM-dd")
    private String createDate;
    @AssertTrue(message = "flag=必須為true")
    private Boolean flag;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getSalary() {
        return salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getCreateDate() {
        return createDate;
    }

    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }

    public Boolean getFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }

    @Override
    public String toString() {
        return "TestRequest{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", salary='" + salary + '\'' +
                ", phone='" + phone + '\'' +
                ", createDate=" + createDate +
                ", flag=" + flag +
                '}';
    }
}

控制器

package net.ybclass.online_ybclass.controller;

import net.ybclass.online_ybclass.model.request.ParamValidRequest;
import net.ybclass.online_ybclass.utils.JsonData;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ParamController {
    @PostMapping("param")
    public JsonData param(@Validated @RequestBody ParamValidRequest request, BindingResult br) {
        //判斷參數是否校驗失敗,若校驗失敗,直接返回錯誤信息
        if (br.hasErrors()) {
            return JsonData.buildError(br.getFieldError().getDefaultMessage());
        }
        System.out.println(request);
        return JsonData.buildSuccess("ok");
    }
}

驗證

補充

  我之前一家公司的,用這種方法不行,然后自己手動寫了個工具類,通過工具類校驗請求參數格式,如下

package com.zcsoft.rc.bms.utils;

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

import com.sharingif.cube.core.exception.validation.ValidationCubeException;
import org.hibernate.validator.HibernateValidator;
/**
 * @ClassName:ValidationUtils
 * @Description:請求參數驗證工具類
 * @Author:chenyb
 * @Date:2020/8/14 9:50 上午
 * @Versiion:1.0
 */
public class ValidationUtils{
    /**
     * 使用hibernate的注解來進行驗證
     *
     */
    private static Validator validator = Validation
            .byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();

    /**
     * 功能描述: <br>
     * 〈注解驗證參數〉
     *
     * @param obj
     * @see [相關類/方法](可選)
     * @since [產品/模塊版本](可選)
     */
    public static  <T> void validate(T obj) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
        // 拋出檢驗異常
        if (constraintViolations.size() > 0) {
            throw new ValidationCubeException(String.format("參數校驗失敗:%s", constraintViolations.iterator().next().getMessage()));
        }
    }
}

控制層

    @RequestMapping(value = "add", method= RequestMethod.POST)
    public SecurityRiskLibaryAddRsp add(SecurityRiskLibaryAddReq req){
        ValidationUtils.validate(req);
        return securityRiskLibaryService.add(req);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM