切面+注解 实现对 业务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();
    }

}

 

 

 

 

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