• SpringBoot系列(3)——AOP实战1-权限&日志


    摘要

    • 实现简单的权限控制
    • 实现简单的日志

    权限控制

    pom

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    

    annotation

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

    aspect

    @Aspect
    @Component
    @Order(1)
    public class PermissionFirstAdvice {
    
        @Pointcut("@annotation(xx.xx.xx.PermissionAnnotation)")
        private void permissionCheck() {
        }
    
        @Around("permissionCheck()")
        public Object permissionCheckFirst(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println(System.currentTimeMillis());
    
            //获取请求参数
            Object[] objects = joinPoint.getArgs();
            String userName = (String) objects[0];
    
            if (!userName.equals("admin")) {
                return "失败";
            }
            return joinPoint.proceed();
        }
    }
    

    controller

    @RestController
    @RequestMapping(value = "/permission")
    public class TestController {
        
        @RequestMapping(value = "/check", method = RequestMethod.POST)
        @PermissionsAnnotation()
        public String getGroupList(@RequestParam String userName) {
            return "Hello "+userName;
        }
    }
    

    日志

    pom

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.5.RELEASE</version>
            <relativePath/>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.5.6</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.70</version>
            </dependency>
        </dependencies>
    

    aspect

    @Aspect
    @Component
    public class OperLogAspect {
    
        //操作切入点
        @Pointcut("@annotation(com.bothsavage.annotation.OperLog)")
        public void operLogPoinCut() {}
    
    
        //正常返回通知
        @AfterReturning(value = "operLogPoinCut()", returning = "keys")
        public void saveOperLog(JoinPoint joinPoint, Object keys) {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
            OperationLog operlog = new OperationLog();
            try {
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();
                String className = joinPoint.getTarget().getClass().getName();
                String methodName = method.getName();
                OperLog opLog = method.getAnnotation(OperLog.class);
                methodName = className + "." + methodName;
                Map<String, String> rtnMap = converMap(request.getParameterMap());
                String params = JSON.toJSONString(rtnMap);
    
                operlog.setOperId(IdUtil.randomUUID());
                operlog.setOperModul(opLog.operModul());
                operlog.setOperType(opLog.operType());
                operlog.setOperDesc(opLog.operDesc());
                operlog.setOperMethod(methodName); // 请求方法
                operlog.setOperRequParam(params); // 请求参数
                operlog.setOperRespParam(JSON.toJSONString(keys)); // 返回结果
                operlog.setOperUri(request.getRequestURI()); // 请求URI
                operlog.setOperCreateTime(new Date()); // 创建时间
    
                //打印日志
                System.out.println(JSON.toJSONString(operlog));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
            //转换request 请求参数
        public Map<String, String> converMap(Map<String, String[]> paramMap) {
            Map<String, String> rtnMap = new HashMap<String, String>();
            for (String key : paramMap.keySet()) {
                rtnMap.put(key, paramMap.get(key)[0]);
            }
            return rtnMap;
        }
    
        //转换异常信息为字符串
        public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
            StringBuffer strbuff = new StringBuffer();
            for (StackTraceElement stet : elements) {
                strbuff.append(stet + "
    ");
            }
            String message = exceptionName + ":" + exceptionMessage + "
    	" + strbuff.toString();
            return message;
        }
    }
    

    实体类

    package com.bothsavage.entity;
    
    import lombok.Data;
    
    import java.util.Date;
    
    @Data
    public class OperationLog {
        private String operId;
        private String operModul;
        private String operType;
        private String operDesc;
        private String OperMethod;
        private String OperRequParam;
        private String OperRespParam;
        private String OperUserId;
        private String OperUserName;
        private String OperIp;
        private String OperUri;
        private Date OperCreateTime;
        private String OperVer;
    }
    

    annotation

    @Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
    @Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
    @Documented
    public @interface OperLog {
        String operModul() default ""; // 操作模块
        String operType() default "";  // 操作类型
        String operDesc() default "";  // 操作说明
    }
    

    controller

    @RestController
    public class TestController {
    
        @GetMapping("/test/{testName}")
        @OperLog(operModul = "测试模块",operType = "test",operDesc = "这个是用来测试的")
        public String test(@PathVariable String testName){
            return  "hello"+testName;
        }
    }
    

    参考

    [1].把自己牛逼到了,在SpringBoot用AOP切面实现一个权限校验...

    [2].Spring AOP 实现功能权限校验功能

    [3].SpringAop实现权限校验与日志打印

    [4].基于Spring AOP实现的权限控制

    [5].使用SpringBoot AOP 记录操作日志、异常日志

    本文作者: Both Savage

    本文链接: https://bothsavage.github.io/2020/12/29/SpringBoot/SpringBoot系列(3)——AOP实战1-权限&日志/

    版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

  • 相关阅读:
    PortalBasic Web 应用开发框架:应用篇(六) —— 公共组件
    如何提高Linq查询的性能
    Distributed SMS Processor
    新书《火球 UML大战需求分析》试读 第一章 大话UML
    UML 软件这是源基地软件大学
    Java多线程编程总结
    [译]扩展JavaScript功能的正确方法
    OEA体验:常用功能3 多对多关系
    MicroOrm.Net
    ASP.NET MVC Model元数据及其定制 [中篇]
  • 原文地址:https://www.cnblogs.com/simon-idea/p/14233342.html
Copyright © 2020-2023  润新知