切面+註解 實現對 業務id 驗證是否存在

	@Override
	public ResultBean<Object> updateAuthenticationPersonalInfo(
			@RequestBody
			@ExistBusinessData(tableName = TableName.DeveloperInfo,fieldCondition = {FieldName.DeveloperIdId,FieldName.UpdateUserUpdateUser})
					PersonalAuthenticationVO personalAuthenticationBean){
		
			return aptitudeService.updateAuthenticationPersonalInfo(personalAuthenticationBean);
			
	}
@Getter
public  enum TableName{
    DeveloperInfo("developer_info");

    TableName(String tableName) {
        this.tableName = tableName;
    }
    private  String tableName;

}
@Getter
public enum FieldName {

    Id("id","id"),
    DeveloperIdId("developerId","id"),
    UpdateUserUpdateUser("updateUser","update_user"),
    ;

    FieldName( String beanFieldName, String jdbcFieldName) {
        this.beanFieldName = beanFieldName;
        this.jdbcFieldName = jdbcFieldName;
    }
    private  String beanFieldName;
    private  String jdbcFieldName;

}

 


/**
 * @author 作者<LiuQi>
 * @ClassName: ExistField
 * @Description: 是否存在 業務數據 註解類
 * @date 2019年10月17日 15:45:35
 * <p>
 * 禁止使用格式化格式代碼
 */
@Documented
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(value =ExistBusinessData.List.class)
public @interface ExistBusinessData {

    /**
     * @Fields  : 期望
     *
     * 如果期望 存在, 那麼就是 true, 如果這條數據不存在 那麼就報錯
     *
     * 如果期望 不存在, 那麼就是 false, 如果這條數據存在 那麼就報錯
     *
     */
    boolean expect() default true;

    /**
     * @Fields  : 表名 . 在哪個表中 判斷他是否存在
    DataRegexType
     */
    @Required
    TableName tableName() ;


    /**
     * @Fields  : 過濾字段名條件
     *
     * 例如 想看看  id 是否存在
     * 那麼就是 id
     * 想看看 id+createUser是否存在
     * 那麼就是 id,createUser
     */
    @Required
    FieldName[] fieldCondition() default FieldName.Id;

    /**
     * @Fields  : 其他補充過濾條件
     *
     * 例如 想看看  id 是否存在
     * 那麼就是 id
     * 想看看 id+createUser是否存在
     * 那麼就是 id,createUser
     */
    String otherWhereSqlCondition() default " and is_del = 0";

    /**
     * @Fields  : 參數或者字段描述
     */
    String description() default "";
    /**
     * @Fields  : error message
     */
    String message() default "";

    /**
     * @Fields  : 用來分組驗證
     */
    Class<?>[] groups() default {};

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

    /**
     * Defines several {@link Pattern} annotations on the same element.
     *
     * @see Pattern
     */
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Documented
    @interface List {

        ExistBusinessData[] value();
    }
}
/**
 * @author 作者<LiuQi>
 * @ClassName: ExistBusinessDataImpl
 * @Description: 業務驗證是否存在該值
 * @date 2019年10月17日 16:00:53
 * <p>
 * 禁止使用格式化格式代碼
 */
@Slf4j
@Aspect
@Component
public class ExistBusinessDataImpl {
    @Autowired
    private ExistDataDao existData;

    /**
     * 攔截要執行的目標方法
     * <p>
     * 這裏主要攔截 controller 以及 service 方法
     * <p>
     * 注意 這裏需要throws Throwable 將異常扔出, 爲了防止try catch後,事務失效
     */
    @Around("   execution(* com.jeejio.developer.service.*.controller..*(..))" +
            "|| execution(* com.jeejio.developer.service.*.service..*(..))" +
            "|| execution(* com.jeejio.developer.service.dao.*..*(..))")
    public Object joinpointMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = null;
        //通過父親得到孩子的方法 得到其 註解
        Class<?>[] objects = Arrays.stream(joinPoint.getArgs()).map(Object::getClass).toArray(Class[]::new);
        try {
            method = joinPoint.getSourceLocation().getWithinType().getDeclaredMethod(joinPoint.getSignature().getName(), objects);
        } catch (NoSuchMethodException e) {
            log.info("無法解析本方法,如果" + joinPoint.getSignature().getName());
        }
        if (null != method) {
            //該方法可以的得到method的註解  後期可以擴展
//            ExistBusinessData methodAnnotation = method.getAnnotation(ExistBusinessData.class);
            //發現這個方法有這些參數
            for (int i = 0; i < method.getParameterCount(); i++) {
                //得到該參數的註解
                Annotation[] annotations = method.getParameterAnnotations()[i];
                //得到該參數的內容
                Map<String, String> paramMap = UTools.convertBean2MapString(joinPoint.getArgs()[i]);
                //找到ExistBusinessData的註解
                for (Annotation annotation : annotations) {
                    if (annotation.annotationType().equals(ExistBusinessData.class)) {
                        //已經判斷了類型,可以閉着眼強轉
                        ExistBusinessData paramAnno = (ExistBusinessData) annotation;
                        //準備拼接sql
                        StringBuffer sql = new StringBuffer();
                        //拼接上必填參數
                        sql.append(paramAnno.tableName().getTableName() + " where 1=1 ");
                        FieldName[] fieldNames = paramAnno.fieldCondition();
                        for (FieldName field : fieldNames) {
                            sql.append(" and " + field.getJdbcFieldName() + " = " + paramMap.get(field.getBeanFieldName()));
                        }
                        //如果有額外的 就加上額外的參數
                        sql.append(paramAnno.otherWhereSqlCondition());
                        System.out.println(sql.toString());
                        log.info("業務驗證是否存在該值 準備執行以下過濾條件 :{} ", sql);
                        boolean existDataResult = existData.existData(sql.toString());
                        //如何 都一樣 那麼正常 否則不行
                        if (existDataResult && paramAnno.expect()) {
                        } else {
                            throw new ServiceException(StringUtils.isEmpty(paramAnno.message())?
                                    JSON.toJSONString(Arrays.stream(fieldNames).map(FieldName::getBeanFieldName).toArray(String[]::new))+"中參數無效"
                                    :paramAnno.message());
                        }
                    }
                }
            }
        }
        return joinPoint.proceed();
    }

}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章