定義一個自定義注解類
/** * @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))); } } } } }