通過自定義注解校驗后台接口請求參數


定義一個自定義注解類

/**
 * @Author 田海超
 * @Date 2019/12/10 10:04
 * @Description TODO 非空注解
 **/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamNotNull {
    // 指定值
    String value() default "";

    // 中文描述
    String describeName() default "";

    //BigDecimal類型保留位數
    int bigDecimalDigit() default -1;
}

在接口對象中使用注解(如若使用代碼,請自行補全set和get方法)

/**
 * @Author 田海超
 * @Date 2019/12/6 15:52
 * @Description TODO 提結接口請求參數VO
 **/
public class RequestObjectDemoVO{
    @ParamNotNull(describeName = "請求/響應序列號")
    private String seqReqNo;//請求/響應序列號
    @ParamNotNull(describeName = "接口類型", value = "prepayment_cf")
    private String interfaceType;//接口類型
    @ParamNotNull(describeName = "接口版本", value = "version1.0.0")
    private String versionNo;//接口版本
    @ParamNotNull(describeName = "進件流水號")
    private String businessNo;//進件流水號
    @ParamNotNull(describeName = "總金額", bigDecimalDigit = 2)
    private String paymentSum;//總金額
    @ParamNotNull(describeName = "本金", bigDecimalDigit = 2)
    private String balance;//本金
    @ParamNotNull(describeName = "利息", bigDecimalDigit = 2)
    private String inte;//利息
    @ParamNotNull(describeName = "保費", bigDecimalDigit = 2)
    private String premium;//保費
    @ParamNotNull(describeName = "服務費", bigDecimalDigit = 2)
    private String commission;//服務費
    @ParamNotNull(describeName = "還款來源", value = "01")
    private String paymentSource;//還款來源   01 客戶還款
}

通過反射使用自定義注解校驗對象屬性值

/**
 * @Author 田海超
 * @Date 2019/12/10 10:36
 * @Description TODO 校驗工具類
 **/
public class VerifyUtils {
    /**
     * @return java.lang.String
     * @Author 田海超
     * @Description //TODO 根據非空校驗注解校驗對象屬性是否為空和字段值是否正確
     * @Date 10:35 2019/12/10
     * @Param [object, errorMessage[] 異常描述:errorMessage[0] -->不為空的異常描述;errorMessage[1] -->值校驗錯誤的異常描述;errorMessage[2] -->數字數位校驗錯誤的異常描述]
     **/
    public static String VerifyNotNullAndValueIsRight(Object object, String... errorMessage) {
        if (object == null) {
            throw new IllegalArgumentException();
        }
        try {
            // 反射獲得對象類屬性列表
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(ParamNotNull.class)) {
                    // 該處使可以獲得私有屬性值
                    field.setAccessible(true);
                    Object value = field.get(object);
                    String annotationValue = field.getAnnotation(ParamNotNull.class).describeName();
                    if (value == null) {
                        return MessageFormat.format(errorMessage[0], annotationValue);
                    }
                    //字符串校驗空字符
                    if (value instanceof String && StringUtils.isBlank((String) value)) {
                        return MessageFormat.format(errorMessage[0], annotationValue);
                    }
                    String idealValue = field.getAnnotation(ParamNotNull.class).value();
                    // 如果配置了指定值,校驗傳入值是否符合要求
                    if (StringUtils.isNotBlank(idealValue)) {
                        if (!idealValue.equals(value)) {
                            return MessageFormat.format(errorMessage[1], annotationValue);
                        }
                        if (value instanceof String && !StringUtils.equals((String) value, idealValue)) {
                            return MessageFormat.format(errorMessage[1], annotationValue);
                        }
                    }
                    // 配置了bigDecimalDigit數目這個字段期望被轉化成digit位的數字,這里添加校驗
                    int digit = field.getAnnotation(ParamNotNull.class).bigDecimalDigit();
                    if (digit != -1 && value instanceof String && errorMessage.length >= 3 && !AbsUtil.checkDoubleNumber((String) value, digit, true)) {// 校驗位數
                        return MessageFormat.format(errorMessage[2], annotationValue);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException("參數非空校驗獲取參數值時異常");
        }
        return "";
    }

    public static void main(String[] args) {
        System.out.println(new BigDecimal(1.02).setScale(2, BigDecimal.ROUND_UP));
        BigDecimal a = new BigDecimal(1.02);
        System.out.println(a.scale());
        System.out.println(a.scale() == 2);
    }
}

*****************************以下是彩蛋*******************

使用反射,我們還可以對接口請求對象和系統返回對象的值進行一一比較:

前提條件:兩個對象要進行比較的對象屬性名要一致!!!!!

/**
     * @return void
     * @Author 田海超
     * @Description //TODO 校驗結算金額正確性
     * @Date 11:14 2019/12/13
     * @Param [vo, resVo]
     **/
    public void verifyAmount(RequestObjectDemoVO_1 vo, RequestObjectDemoVO_2 resVo) throws Exception{
        Field[] fields = vo.getClass().getDeclaredFields();
        Class c = resVo.getClass();
        for (Field field : fields) {
            if (field.isAnnotationPresent(ParamNotNull.class)) {
                field.setAccessible(true);
                int digit = field.getAnnotation(ParamNotNull.class).bigDecimalDigit();
                if (digit != -1) {// 金額類型--注解類ParamNotNull中的默認值是-1,不等於-1說明配置了小數位數,表明是金額字段
                    Object value = field.get(vo);
                    // 根據循環屬性列表的屬性名稱獲得要比較的對象屬性Field對信息
                    Field resVoField = c.getDeclaredField(field.getName());
                    resVoField.setAccessible(true);
                    BigDecimal val = (BigDecimal) resVoField.get(resVo);
//                    System.out.println(val.toPlainString());
                    if (val != null && !val.toPlainString().equals(value)) {
                        String describeName = field.getAnnotation(ParamNotNull.class).describeName();
                        throw new DefinedException(getSimpleResJson("0102", MessageFormat.format("報文內容錯誤:{0}不正確", describeName)));
                    }
                }
            }
        }
    }


免責聲明!

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



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