大壮个人博客

愿居于一城,与卿所见美好......

推荐文章

Hexo博文置顶(自定义排序)

    HEXO默认是按照时间顺序排一条线,然后按照时间顺序来决定显示的顺序的。按照网上的教程整理了一份方法。

    Hexo博文置顶(自定义排序)

    修改Hexo文件夹下的node_modules/hexo-generator-index/lib/generator.js

    打开在最后添加如下javascript代码

    posts.data = posts.data.sort(function(a, b) {
    }
        return -1;
    }
        return 1;
    }
    else return b.date - a.date; // 都没定义按照文章日期降序排
    

    });

    文章有多种属性,一个一个添加是不是很麻烦呢?

    这个时候可以修改:HEXO博客的scaffolds\post.md

    阅读全文>>

作者:大壮分类:【javaEE浏览(557评论(0

2020-12-25 22:22:23

sharehoo社区自定义注解实现登陆状态校验

    Spring AOP

    Spring AOP 即面向切面,是对OOP面向对象的一种延伸。
    AOP机制可以让开发者把业务流程中的通用功能抽取出来,单独编写功能代码。在业务流程执行过程中,Spring框架会根据业务流程要求,自动把独立编写的功能代码切入到流程的合适位置。

    我们通过AOP机制可以实现:Authentication 权限检查、Caching 缓存、Context passing 内容传递、Error handling 错误处理、日志打印等功能,这里我们讲一下怎么用Spring AOP来实现权限检查。

    SpringBoot 通过自定义注解实现权限检查

    Maven依赖

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.2</version>
        <optional>true</optional>
    </dependency>
    
    <!--Spring AOP-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    MyPermissionTag.class自定义注解

    • @Retention: 用来修饰注解,是注解的注解,称为元注解。
    • @Target:用来说明对象的作用范围
    /**
     * 用户请求权限校验
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface MyPermissionTag {
        String value() default "";
        String name() default "";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里特别讲一下@Retention,按生命周期来划分可分为3类:

    • RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃(运行时去动态获取注解信息);
    • RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期(在编译时进行一些预处理操作);
    • RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在(做一些检查性的操作);

    这3个生命周期分别对应于:Java源文件(.java文件) —> .class文件 —> 内存中的字节码。

    AuthInterceptor 权限检查的切面

    这里简单介绍一下,切面的执行方法和其执行顺序:

    • @Around 通知方法将目标方法封装起来
    • @Before 通知方法会在目标方法调用之前执行
    • @After 通知方法会在目标方法返回或者异常后执行
    • @AfterReturning 通知方法会在目标方法返回时执行
    • @Afterthrowing 通知方法会在目标方法抛出异常时执行

    这里以一个返回正常的情况为例:(异常替换最后一步即可)

    HasLoginAspect.class

    • 注意要在启动类扫描这个class,并且添加 @EnableAspectJAutoProxy(proxyTargetClass = true)
    package com.sharehoo.config.aspect;
    import com.alibaba.fastjson.JSONObject;
    import com.sharehoo.config.lang.Consts;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.util.ObjectUtils;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    /**
     * @Author miki
     * @Description 用户是否登录的鉴权注解 *
     * @Date 14:48 2020/11/30
     * @Param
     * @return
     **/
    
    
    @Component
    @Aspect
    @SuppressWarnings({"unused"})
    public class HasLoginAspect {
    	
    	public static final Logger logger = LoggerFactory.getLogger(HasLoginAspect.class);
    
    	public HasLoginAspect(){
    	    logger.info("创建aop切面拦截...");
        }
    
        /**
         * 参数处理
         *
         * @param point
         */
        @Before("@annotation(com.sharehoo.config.annotation.HasLogin)")
        public void beforeProReq(JoinPoint point) {
            logger.info("前置拦截-开始");
    
            logger.info("前置拦截-结束");
        }
    
    
        @Around("@annotation(com.sharehoo.config.annotation.HasLogin)")
        public Object checkRequestHead(ProceedingJoinPoint joinPoint) throws Throwable {
            logger.debug("===>check access token start:{}", joinPoint.getArgs());
            long begin = System.nanoTime();
    
            HttpServletRequest request =
                    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            request.setCharacterEncoding("UTF-8");
            HttpServletResponse response =
                    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    
            HttpSession session = request.getSession();
            Object user= session.getAttribute(Consts.CURRENTUSER);
    
            String requestUri = request.getRequestURI();
            String requestMethod = request.getMethod();
    
            logger.info(
                    "===>get the equest url:{}; and request method:{}; ",
                    requestUri, requestMethod);
    
            long end = System.nanoTime();
            logger.info("API deal time log {}:{}",
                    joinPoint.getTarget().getClass() + "." + joinPoint.getSignature().getName(),
                    (end - begin) / 1000000);
            if(ObjectUtils.isEmpty(user)){
                response.sendRedirect("http://sharehoo.cn/login?prePage=http://sharehoo.cn" + requestUri);
                return null;
            }
    
            return joinPoint.proceed();
        }
    
    
        /**
         * 参数处理
         *
         * @param point
         */
        @After("@annotation(com.sharehoo.config.annotation.HasLogin)")
        public void afterProReq(JoinPoint point) {
    
            logger.info("登录校验拦截-结束");
        }
    }
    阅读全文>>

作者:大壮分类:【javaEE浏览(227评论(0

2020-12-07 20:28:26