天天看點

現實場景中的自定義校驗

最近這段時間業務提了很多關于字段校驗的需求,當然嚴格的字段校驗能保持資料的完整性。

首先就是非空校驗,項目用的springBoot 2.0版本其中的非空驗證用的是 @Valid标簽,

其中代碼部分如下實作

@RequestMapping(value = "/Done", method = {RequestMethod.GET,RequestMethod.POST})
    public String Done(@RequestBody @Valid VerificationEntity request, BindingResult result) {
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            StringBuilder stringBuilder = new StringBuilder();
            for (ObjectError error : errors) {
                stringBuilder.append(error.getDefaultMessage()).append("|");
            }
            return "false";
        }
        return "";
  }


@Data
public class VerificationEntity implements Serializable {

    private static final long serialVersionUID = -1672680939195600441L;

    @Valid
    @NotBlank(message = "姓名不能為空")
    public String name;

    @Valid
    @NotBlank(message = "年齡不能為空")
    public String age;

    public String sex;
}
           

然後就是一些自定義的校驗規則,因為規則衆多之舉幾個簡單的例子,

首先是劃分是哪個接口業務攔截,下單接口、退費接口、投訴接口等規則邏輯,這是最外層的校驗攔截,為什麼不講校驗用AOP攔截呢,寫進AOP的話,所有的接口都會校驗,但是現實情況,不至于這麼廣泛的校驗。

現實場景中的自定義校驗

代碼結構

public interface ComplainVerificationService<T> {

    /**
     * 投訴接口業務邏輯校驗
     * @param agencyCode
     * @param t
     * @return
     */
    VerificationResult complainValid(String agencyCode, T t);
}


public interface DoneVerificationService <T> {

    /**
     * 成交接口業務規則校驗
     * @param agencyCode
     * @param t
     * @return
     */
    VerificationResult doneValid(String agencyCode, T t);
}

public interface RefundVerificationService<T> {

    /**
     * 退費業務校驗
     * @param agencyCode
     * @param t
     * @return
     */
    VerificationResult refundValid(String agencyCode, T t);
}
           

2.然後就是業務層級别的資料校驗,例如 下單接口和退費接口公用的人員年齡校驗,退費接口和投訴接口公用的人員職業校驗,下單和投訴接口的人員性别校驗。當然這些都是一些簡單的例子,整體的校驗思想是類似的,首先是自定義的接口類分類,每個業務級别的校驗都是獨立的接口,如上述所說的 年齡校驗、職業校驗、以及性别校驗,為了保持自定義校驗的統一性和複用性,每一個接口都是特定的入參和傳回值,這樣可以最大程度的統一化。

public interface ageVerificationService {

    boolean validAge(ageDto ageDto);
}


@Log4j
@Service
public class ageVerificationServiceImp implements ageVerificationService {

    @Override
    public boolean validAge(ageDto ageDto) {
        /**
         * todo 這裡做最主要的業務檢驗
         */
        return false;
    }
}
           

當然自定義接口的分類,必須按照具體的業務邏輯設計,如電商系統的話,最好是産品校驗、流程校驗、收費校驗等等這種次元,劃分原則就是業務上最容易變化的點作為原子。

然後就是管道自定義的代碼實作,為了簡明扼要,用其中兩個管道進行校驗規則的舉例。

@Service
public class ChannelA implements DoneService,ComplainService,ComplainVerificationService {

    @Resource
    private ageVerificationService ageVerification;

    @Resource
    private jobVerificationService jobVerification;

    @Override
    public void done(String params) {
        //todo 實作成交
    }

    @Override
    public void complain(String params) {
        //todo 實作投訴
    }

    @Override
    public VerificationResult complainValid(String agencyCode, Object o) {
        /**
         * 管道A進行成交業務校驗
         * 1.校驗年齡
         * 2.校驗職業
         */
       boolean ageBoo= ageVerification.validAge(new ageDto());
       boolean jobBoo=jobVerification.validJob(new jobDto());
       return null;
    }
}

@Service
public class ChannelB implements DoneService,RefundService,ComplainVerificationService {

    @Resource
    private jobVerificationService jobVerification;

    @Resource
    private sexVerificationService sexVerification;

    @Override
    public void refund(String params) {
        //todo 實作退費
    }

    @Override
    public void done(String params) {
        //todo 實作成交
    }

    @Override
    public VerificationResult complainValid(String agencyCode, Object o) {
        /**
         * 管道A進行成交業務校驗
         * 1.職業校驗
         * 2.性别校驗
         */
        boolean ageBoo= sexVerification.validSex(new sexDto());
        boolean jobBoo=jobVerification.validJob(new jobDto());
        return null;
    }
}
           

總結:這種校驗思想,主要分為三層。

一層是對外接口類層面,主要是為第三方提供的接口進行業務層次的劃分。

二層是固定的機關實體,主要是第三方固定的管道級别。

三層就是容易變化的業務規則,這層就是上述提到的最小的機關原子。