Spring 注解

@Target({ElementType.METHOD})  注解的适用范围
@Retention(RetentionPolicy.RUNTIME)  注解的生命周期

可以使用拦截器Interceptor处理注解,也可以定义切面Aspect

SysLog

加上该注解后,方法调用后生成SysLogEntity,记录方法调用的相关信息(请求参数,方法名,请求用户)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {

    String value() default "操作日志";

    /**
     * 是否保存请求的参数
     */
    public boolean isSaveRequestData() default true;

    /**
     * 是否保存响应的参数
     */
    public boolean isSaveResponseData() default false;
}

SysLogAspect

注解切面

    @Before(value = "@annotation(controllerLog)")
    public void doBefore(JoinPoint joinPoint, SysLog controllerLog) {
        startTime.set(System.currentTimeMillis());
    }

    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "@annotation(controllerLog)" , returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, SysLog controllerLog, Object jsonResult) {
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - startTime.get();
        handleLog(joinPoint, controllerLog, null, jsonResult, time);
    }


    protected void handleLog(final JoinPoint joinPoint, SysLog controllerLog, final Exception e, Object jsonResult, long time) {
        try {
            // 获取当前的用户
            SysUserEntity loginUser = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();

            // *========数据库日志=========*//
            SysLogEntity sysLog = new SysLogEntity();
            //注解上的描述
            // 请求的地址
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            sysLog.setIp(ip);
//            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
            //请求的参数
            Object[] args = joinPoint.getArgs();
            if (loginUser != null) {
                sysLog.setUserName(loginUser.getUserName());
            } else {
                sysLog.setUserName(((SysLoginForm) args[0]).getUserName());
            }

//            if (e != null) {
//                operLog.setStatus(BusinessStatus.FAIL.ordinal());
//                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
//            }
            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            sysLog.setMethod(className + "." + methodName + "()");
            sysLog.setTime(time);
            sysLog.setCreateTime(new Date());
            // 设置请求方式
//            sysLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            // 处理设置注解上的参数
            getControllerMethodDescription(joinPoint, controllerLog, sysLog, jsonResult);
            // 保存数据库
            AsyncManager.me().execute(AsyncFactory.recordOper(sysLog));
        } catch (Exception exp) {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}" , exp.getMessage());
            exp.printStackTrace();
        }
    }

    

RedisCace

加上该注解后,方法执行前查询Redis 是否存在缓存,如果不存在,则将方法执行后的结果存储进Redis 中。如果存在,则直接返回缓存。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface RedisCache {
    /**
     * 缓存key
     * 若destine为true,存入redis的键为cacheKey的值
     * 若destine为false,存入redis的的键为service方法的 cacheKey:userId_id_packageName.className.methodName
     */
    String cacheKey() default Constant.SYS_CACHE;

    /**
     * 数据缓存时间单位s秒 默认5分钟
     */
    int cacheTime() default 300;

    /**
     * 是否使用指定的key
     * 若为true,存入redis的键为cacheKey的值
     */
    boolean destine() default false;
}

RedisCacheAspect

注解切面

@Slf4j
@Aspect
@Component
public class RedisCacheAspect {

    @Autowired
    private JedisUtil jedisUtil;

    @Pointcut("@annotation(com.tbo.canal.common.annotation.RedisCache)")
    public void webAspect() {
    }

    @SuppressWarnings("unchecked")
    @Around("webAspect()")
    public Object redisCache(ProceedingJoinPoint pjp) throws Throwable {
        //得到类名、方法名和参数
        String redisResult;
        String className = pjp.getTarget().getClass().getName();
        String methodName = pjp.getSignature().getName();
        Object[] args = pjp.getArgs();

        //得到被代理的方法
        Signature signature = pjp.getSignature();
        if (!(signature instanceof MethodSignature)) {
            throw new IllegalArgumentException();
        }
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = pjp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        //得到被代理的方法上的注解
        String cacheKey = method.getAnnotation(RedisCache.class).cacheKey();
        int cacheTime = method.getAnnotation(RedisCache.class).cacheTime();
        boolean destine = method.getAnnotation(RedisCache.class).destine();

        String key = cacheKey;
        if (!destine) {
            //根据类名,方法名和参数生成key
            key = StringUtils.genKey(cacheKey, className, methodName);
        }
        log.debug("生成的key[{}]", key);

        Object result;
        if (!jedisUtil.exists(key)) {
            log.debug("缓存未命中");
            //缓存不存在,则调用原方法,并将结果放入缓存中
            result = pjp.proceed(args);
            redisResult = JSON.toJSONString(result);
            jedisUtil.setObject(key, redisResult, cacheTime);
        } else {
            //缓存命中
            log.debug("缓存命中");
            redisResult = JSONObject.toJSON(jedisUtil.getObject(key)).toString();
            //得到被代理方法的返回值类型
            Class returnType = method.getReturnType();
            result = JSON.parseObject(redisResult, returnType);
        }
        return result;
    }
}

PassToken

加上该注解后,方法执行不需要校验token。

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean value() default true;
}

拦截器

@Component
public class JwtInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        //如果不是映射到方法直接放行
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        Method method = handlerMethod.getMethod();
        if (method.isAnnotationPresent(PassToken.class)) { //方法上面是否有注解?
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.value()){
                return true;
            }else {
                HashMap<String,String> hashMap = new HashMap<>();
                String token = request.getHeader("token");
                try {
                 boolean ver= TokenUtil.verify(token) ;
                    if (ver){
                        return  true;
                    }else{
                        hashMap.put("msg","token无效");
                        hashMap.put("code","401");
                    }
                }catch (SignatureVerificationException e){
                    e.printStackTrace();
                    hashMap.put("msg","签名不一致");
                }catch (TokenExpiredException e){
                    e.printStackTrace();
                    hashMap.put("msg","令牌过期异常");
                }catch (AlgorithmMismatchException e) {
                    e.printStackTrace();
                    hashMap.put("msg", "算法不匹配异常");
                }catch (InvalidClaimException e){
                    e.printStackTrace();
                    hashMap.put("msg","失效的claim异常");
                }catch (Exception e){
                    e.printStackTrace();
                    hashMap.put("msg","token无效");
                    hashMap.put("code","401");
                }
                String resultJson = JSON.toJSONString(hashMap);
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().print(resultJson);
                return false;
            }
        }
        HashMap<String,String> hashMap = new HashMap<>();
        String token = request.getHeader("token");
        try {
           boolean ver= TokenUtil.verify(token);
            if (ver){
                return true;
            }else {
                hashMap.put("msg","token无效");
                hashMap.put("code","401");
            }
        }catch (SignatureVerificationException e){
            e.printStackTrace();
            hashMap.put("msg","签名不一致");
        }catch (TokenExpiredException e){
            e.printStackTrace();
            hashMap.put("msg","令牌过期异常");
        }catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            hashMap.put("msg", "算法不匹配异常");
        }catch (InvalidClaimException e){
            e.printStackTrace();
            hashMap.put("msg","失效的claim异常");
        }catch (Exception e){
            e.printStackTrace();
            hashMap.put("msg","token无效");
            hashMap.put("code","401");
        }
        String resultJson = JSON.toJSONString(hashMap);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().print(resultJson);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值