springboot 实现登录拦截,使用AOP

什么是AOP,面向切面的工程,可以通过类似于插入一个切点以实现一些业务,比如我们要做的登录拦截。

1.自定义注解

//注解使用在哪个上面
@Target({ElementType.METHOD})
//生命周期,在执行的时候
@Retention(RetentionPolicy.RUNTIME)
//
@Documented
@Mapping
//自定义注解类@GlobalInterceptor
public @interface GlobalInterceptor {


    /***
     * 校验参数
     *
     * @return
     */
    boolean checkParams() default false;

    /***
     * 登录拦截器
     * @return
     */
    boolean checkLogin() default false;

    /***
     * 校验超级管理员
     * @return
     */
    boolean checkAdmin() default false;

}

2.声明切面类

  1. 声明切面类@Aapect

  2. 设置切点@Pointcut(@annotation(com.easypan.annotation.GlobalInterceptor))

  3. 设置执行方法@Before("requsetInterceptor"),在切点前进行执行

//声明是个切面类
@Aspect
//声明是个spring类的组件,并指定bean名
@Component("globalOperatcionAspect")
public class GlobalOperatcionAspect {

    private static final Logger logger = LoggerFactory.getLogger(GlobalOperatcionAspect.class);

    //定义基本需要校验的类型
    private static final String TYPE_BASE[] = {"java.lang.String", "java.lang.Integer",  "java.lang.Long"};

    private final OrderedFormContentFilter formContentFilter;

    public GlobalOperatcionAspect(OrderedFormContentFilter formContentFilter) {
        this.formContentFilter = formContentFilter;
    }

    //定义切点,加了@GlobalInterceptor()进行拦截
    @Pointcut("@annotation(com.easypan.annotation.GlobalInterceptor)")
    //请求拦截
    private void requsetInterceptor() {

    }

    //在切点方法requsetInterceptor()之前执行
    @Before("requsetInterceptor()")
    public void interceptorDo(JoinPoint point) throws BusinessException {

        try{
            //拿到的目标
            Object target = point.getTarget();
            //可以拿到的参数
            Object[] args = point.getArgs();
            String methodName = point.getSignature().getName();
            //获取参数类型
            Class<?>[] parameterTypes = ((MethodSignature)point.getSignature()).getParameterTypes();
            //反射获取方法对象,sendEmailCode
            Method method = target.getClass().getMethod(methodName, parameterTypes);
            // 获取方法上的GlobalInterceptor注解
            GlobalInterceptor interceptor = method.getAnnotation(GlobalInterceptor.class);

            //没用注解直接返回,没有@GlobalInterceptor(checkParams = true)
            if (interceptor == null) {
                return;
            }

            /***
             * 校验登录
             */
            if(interceptor.checkLogin() || interceptor.checkAdmin()){
                checkLogin(interceptor.checkAdmin());
            }

            /***
             * 参数校验
             */
            if (interceptor.checkParams()){
                validateParams(method, args);
            }

        } catch (BusinessException e){
            logger.error("全局拦截器异常");
            throw e;
        } catch (Exception e) {
            logger.error("全局拦截器异常");
            throw new BusinessException(ResponseCodeEnum.CODE_500);
        } catch (Throwable e){
            logger.error("全局拦截器异常");
            throw new BusinessException(ResponseCodeEnum.CODE_500);
        }
    }

3.设置检查点(参数验证,登录验证)

可以设置检查点的有下面三个

public @interface GlobalInterceptor {


    /***
     * 校验参数
     *
     * @return
     */
    boolean checkParams() default false;

    /***
     * 登录拦截器
     * @return
     */
    boolean checkLogin() default false;

    /***
     * 校验超级管理员
     * @return
     */
    boolean checkAdmin() default false;

}

验证是否需要登录

private void checkLogin(boolean checkAdmin) throws BusinessException {
    //在方法类中获得session对象
    HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    HttpSession session = request.getSession();
    SessionWebUserDto userDto = (SessionWebUserDto)session.getAttribute(Constants.SESSION_KEY);

    if(null == userDto){
        throw new BusinessException(ResponseCodeEnum.CODE_600);
    }

    if(checkAdmin && !userDto.getAdmin()){
        throw new BusinessException(ResponseCodeEnum.CODE_404);
    }
}

使用方法

添加注解@GlobalInterceptor(checkLogin = True)

如果没有登录,会报错。

参数验证

//校验方法
private void validateParams(Method m, Object[] args) throws BusinessException {
    Parameter[] paramters = m.getParameters();
    for (int i = 0; i < paramters.length; i++) {
        //参数类型
        Parameter param = paramters[i];
        //参数的值
        Object value = args[i];

        //获取参数上的VerifyParam注解
        VerifyParam verifyParam = param.getAnnotation(VerifyParam.class);

        if (verifyParam == null) {
            continue;
        }

        //是否是基本类型,进行基本校验
        if(ArrayUtils.contains(TYPE_BASE, param.getParameterizedType().getTypeName())){
            checkValue(value, verifyParam);
        }else{

        }

    }
}

    private void checkValue(Object value, VerifyParam verifyParam) throws BusinessException {
        Boolean isEmpty = value==null || StringTools.isEmpty(value.toString());
        Integer length = value==null?0:value.toString().length();

        /***
         * 校验空
         */
        if(isEmpty && verifyParam.required()){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        /***
         * 校验长度
         */
        if(!isEmpty && (verifyParam.max() != -1 && length > verifyParam.max()||verifyParam.min() != -1 && length < verifyParam.min())){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

        /***
         * 校验正则
         */
        if(! isEmpty && !StringTools.isEmpty(verifyParam.regex().getRegex()) && !VerifyUtils.verify(verifyParam.regex(), String.valueOf(value))){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

    }

使用方法:

@GlobalInterceptor(checkParams = true)
public ResponseVO changeFileFolder(HttpSession session,
                         @VerifyParam(required = true) String fileIds,
                            @VerifyParam(required = true) String filePid
                            ){
    SessionWebUserDto webUserDto = getUserInfoFromSession(session);
    fileInfoService.changeFileFolder(fileIds, filePid, webUserDto.getUserId());
    //List<FileInfo> fileInfoList = fileInfoService.findListByParam(infoQuery);
    return getSuccessResponseVO(null);
}
  1. @GlobalInterceptor(checkParams = true, checkLogin = false)

  2. @VerfyParam(min = 1, max = 100, required = true, regex = VerifyRegexEnum.EMAIL) ,最大值,最小值,正则化,是否需要验证

  3. 其中VerifyParam verifyParam = param.getAnnotation(VerifyParam.class);使用参数上的注解内容

3.使用@GlobalInterceptor进行登录拦截

@RequestMapping("/login")
//需要参数验证,不需要登录
@GlobalInterceptor(checkParams = true, checkLogin = false)
public ResponseVO login(HttpSession session,
                      @VerifyParam(required = true) String email,
                      @VerifyParam(required = true) String password,
                      @VerifyParam(required = true) String checkCode) throws BusinessException {
    try{
       //判断图像验证码是否正确
       if (!checkCode.equalsIgnoreCase(key_code)) {
          throw new BusinessException("图片验证码不正确");
       }
       //
       SessionWebUserDto sessionWebUserDto = userInfoService.login(email, password);
       session.setAttribute(Constants.SESSION_KEY, sessionWebUserDto);

       return getSuccessResponseVO(sessionWebUserDto);
    } finally {
       session.removeAttribute(Constants.CHECK_CODE_KEY);
       key_code = null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值