spring boot自定义注解拦截接口

2023-05-16

自定义注解,拦截接口请求

maven依赖管理

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

1 注解编写

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

    @AliasFor("title")
    String value() default "" ;

    /**
     * 模块
     */
     String title() default "";

     HttpMethod method() default HttpMethod.GET;



    /**
     * 是否登录用户
     * @return
     */
    boolean isLogin() default true;

    /**
     * 如果非登录用户 传入client作为操作人
     * @return
     */
    String client() default "";

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

2 编写AOP

2.1 定义pointCut

    @Pointcut("@annotation(com.lcfc.common.log.annotation.AuditLog)")
    public void logPointCut(){}

2.2 定义处理完请求后操作

 @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
    {
        handleLog(joinPoint, null, jsonResult);
    }

2.3 定义异常操作

@AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e)
    {
        handleLog(joinPoint, e, null);
    }

完成代码

@EnableFeignClients(basePackages = {"com.lcfc"})
@Slf4j
@Component
@Aspect
public class AuditLogAspect {

    @Autowired
    AuditLogService logService;

    @Autowired
    Environment env;

    //是否使用大文件存储
    @Value("${logging.large.store:true}")
    private Boolean largeStore;


    @Pointcut("@annotation(com.lcfc.common.log.annotation.AuditLog)")
    public void logPointCut(){}

    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
    {
        handleLog(joinPoint, null, jsonResult);
    }

    /**
     * 拦截异常操作
     *
     * @param joinPoint 切点
     * @param e 异常
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e)
    {
        handleLog(joinPoint, e, null);
    }


    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)
    {
        try
        {
            // 获得注解
            AuditLog controllerLog = AspectUtils.getAnnotation(joinPoint,AuditLog.class);
            if (controllerLog == null)
            {
                return;
            }

            // *========数据库日志=========*//
            AuditLogEntity operLog = new AuditLogEntity();
            operLog.setStatus(Integer.valueOf(Constants.NORMAL));
            // 请求的地址
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            operLog.setOperIp(ip);

            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());

            // 设置请求方式
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());

            // 是否需要保存request,参数和值
            if (controllerLog.isSaveRequestData())
            {
                // 获取参数的信息,传入到数据库中。
                setRequestValue(joinPoint, operLog);
            }

            saveLog(controllerLog,operLog,joinPoint,e,jsonResult);

        }
        catch (Exception exp)
        {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }

    public void saveLog(AuditLog log,AuditLogEntity operLog,final JoinPoint joinPoint,final Exception e,Object jsonResult) throws Exception {

        // 设置action动作
        operLog.setBusinessType(log.method().ordinal());
        // 设置模块
        operLog.setTitle(log.title());
        //设置应用名
        String appName = env.getProperty("spring.application.name");
        if (StringUtils.isNotBlank(appName)){
            operLog.setOperApp(appName);
        }

        operLog.setCreateTime(new Date());
        // 返回参数
        String res = JSONObject.toJSONString(jsonResult);
        operLog.setHasCompress(Integer.valueOf(Constants.NORMAL));
        // 字符大于规定 同时不支持大文件存储
        if (res.length()>Constants.STORE_LENGTH.intValue()
                &&!largeStore){
            res = GZIPUtils.compress(res);
            operLog.setHasCompress(Integer.valueOf(Constants.EXCEPTION));
        }
        operLog.setJsonResult(res);

        if (log.isLogin()){
            String username = SecurityUtils.getUsername();
            if (StringUtils.isNotBlank(username))
            {
                operLog.setOperName(username);
                operLog.setCreateBy(username);
            }
        }else if (StringUtils.isNoneBlank(log.client())){
            String username = log.client();
            operLog.setOperName(username);
            operLog.setCreateBy(username);
        }


        if (e != null)
        {
            operLog.setStatus(Integer.valueOf(Constants.EXCEPTION));
            operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
        }
        // 设置方法名称
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        operLog.setMethod(className + "." + methodName + "()");

        ApiOperation operation = AspectUtils.getAnnotation(joinPoint,ApiOperation.class);

        if (operation!=null){
            operLog.setOperDesc(operation.value());
        }

        // 设置操作人类别
//        operLog.setOperatorType(log.operatorType().ordinal());


        // 保存数据库
        logService.saveLog(operLog);
    }



    /**
     * 获取请求的参数,放到log中
     *
     * @param operLog 操作日志
     * @throws Exception 异常
     */
    private void setRequestValue(JoinPoint joinPoint, AuditLogEntity operLog) throws Exception
    {
        String params = argsArrayToString(joinPoint.getArgs());
        operLog.setOperParam(StringUtils.substring(params, 0, 2000));
    }


    /**
     * 参数拼装
     */
    private String argsArrayToString(Object[] paramsArray)
    {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0)
        {
            for (int i = 0; i < paramsArray.length; i++)
            {
                if (paramsArray[i]!=null&&!isFilterObject(paramsArray[i]))
                {
                    try
                    {
                        Object jsonObj = JSONObject.toJSON(paramsArray[i]);
                        params += jsonObj.toString() + " ";
                    }
                    catch (Exception e)
                    {
                    }
                }
            }
        }
        return params.trim();
    }

    /**
     * 判断是否需要过滤的对象。
     *
     * @param o 对象信息。
     * @return 如果是需要过滤的对象,则返回true;否则返回false。
     */
    @SuppressWarnings("rawtypes")
    public boolean isFilterObject(final Object o)
    {
        Class<?> clazz = o.getClass();
        if (clazz.isArray())
        {
            return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
        }
        else if (Collection.class.isAssignableFrom(clazz))
        {
            Collection collection = (Collection) o;
            for (Iterator iter = collection.iterator(); iter.hasNext();)
            {
                return iter.next() instanceof MultipartFile;
            }
        }
        else if (Map.class.isAssignableFrom(clazz))
        {
            Map map = (Map) o;
            for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
            {
                Map.Entry entry = (Map.Entry) iter.next();
                return entry.getValue() instanceof MultipartFile;
            }
        }
        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
    }

}

help

Aspect 工具类

/**
 * AOP 工具类
 */
@UtilityClass
public class AspectUtils {

    /**
     * 是否存在注解,如果存在就获取
     * @return
     */
    public  static  <T> T getAnnotation(JoinPoint joinPoint, Class clazz) throws Exception
    {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null)
        {
            return (T)method.getAnnotation(clazz);
        }
        return null;
    }

}

servlet 工具类

public class ServletUtils {
    /**
     * 获取String参数
     */
    public static String getParameter(String name)
    {
        return getRequest().getParameter(name);
    }

 

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest()
    {
        try
        {
            return getRequestAttributes().getRequest();
        }
        catch (Exception e)
        {
            return null;
        }
    }
    
    
    public static ServletRequestAttributes getRequestAttributes()
    {
        try
        {
            RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
            return (ServletRequestAttributes) attributes;
        }
        catch (Exception e)
        {
            return null;
        }
    }


    /**
     * 获取response
     */
    public static HttpServletResponse getResponse()
    {
        try
        {
            return getRequestAttributes().getResponse();
        }
        catch (Exception e)
        {
            return null;
        }
    }

    /**
     * 获取session
     */
    public static HttpSession getSession()
    {
        return getRequest().getSession();
    }


    public static Map<String, String> getHeaders(HttpServletRequest request)
    {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        if (enumeration != null)
        {
            while (enumeration.hasMoreElements())
            {
                String key = enumeration.nextElement();
                String value = request.getHeader(key);
                map.put(key, value);
            }
        }
        return map;
    }

    /**
     * 将字符串渲染到客户端
     * 
     * @param response 渲染对象
     * @param string 待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string)
    {
        try
        {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name)
    {
        return  Integer.valueOf(getRequest().getParameter(name));
    }



}

ip 工具类

public class IpUtils {

    public static String getIpAddr(HttpServletRequest request)
    {
        String ip = null;

        // X-Forwarded-For:Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
        {
            // Proxy-Client-IP:apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
        {
            // WL-Proxy-Client-IP:weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
        {
            // HTTP_CLIENT_IP:有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
        {
            // X-Real-IP:nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        // 有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0)
        {
            ip = ipAddresses.split(",")[0];
        }

        // 还是不能获取到,最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
        {
            ip = request.getRemoteAddr();
        }
        return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
    }

    public static boolean internalIp(String ip)
    {
        byte[] addr = textToNumericFormatV4(ip);
        return internalIp(addr) || "127.0.0.1".equals(ip);
    }

    private static boolean internalIp(byte[] addr)
    {
        if (addr==null || addr.length < 2)
        {
            return true;
        }
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        // 10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        // 172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        // 192.168.x.x/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0)
        {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4)
                {
                    return true;
                }
            case SECTION_5:
                switch (b1)
                {
                    case SECTION_6:
                        return true;
                }
            default:
                return false;
        }
    }

    /**
     * 将IPv4地址转换成字节
     *
     * @param text IPv4地址
     * @return byte 字节
     */
    public static byte[] textToNumericFormatV4(String text)
    {
        if (text.length() == 0)
        {
            return null;
        }

        byte[] bytes = new byte[4];
        String[] elements = text.split("\\.", -1);
        try
        {
            long l;
            int i;
            switch (elements.length)
            {
                case 1:
                    l = Long.parseLong(elements[0]);
                    if ((l < 0L) || (l > 4294967295L)){
                        return null;
                    }
                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 2:
                    l = Integer.parseInt(elements[0]);
                    if ((l < 0L) || (l > 255L)) {
                        return null;
                    }
                    bytes[0] = (byte) (int) (l & 0xFF);
                    l = Integer.parseInt(elements[1]);
                    if ((l < 0L) || (l > 16777215L)) {
                        return null;
                    }
                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 3:
                    for (i = 0; i < 2; ++i)
                    {
                        l = Integer.parseInt(elements[i]);
                        if ((l < 0L) || (l > 255L)) {
                            return null;
                        }
                        bytes[i] = (byte) (int) (l & 0xFF);
                    }
                    l = Integer.parseInt(elements[2]);
                    if ((l < 0L) || (l > 65535L)) {
                        return null;
                    }
                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 4:
                    for (i = 0; i < 4; ++i)
                    {
                        l = Integer.parseInt(elements[i]);
                        if ((l < 0L) || (l > 255L)) {
                            return null;
                        }
                        bytes[i] = (byte) (int) (l & 0xFF);
                    }
                    break;
                default:
                    return null;
            }
        }
        catch (NumberFormatException e)
        {
            return null;
        }
        return bytes;
    }

    public static String getHostIp()
    {
        try
        {
            return InetAddress.getLocalHost().getHostAddress();
        }
        catch (UnknownHostException e)
        {
        }
        return "127.0.0.1";
    }

    public static String getHostName()
    {
        try
        {
            return InetAddress.getLocalHost().getHostName();
        }
        catch (UnknownHostException e)
        {
        }
        return "未知";
    }

}

压缩工具类

public class GZIPUtils {
    /**
     * 使用gzip进行压缩
     */
    public static synchronized String compress(String primStr) {
        if (primStr == null || primStr.length() == 0) {
            return primStr;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = null;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(primStr.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (gzip != null) {
                try {
                    gzip.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return new sun.misc.BASE64Encoder().encode(out.toByteArray());
    }

    /**
     * 使用gzip进行解压缩
     */
    public static synchronized String uncompress(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = null;
        GZIPInputStream ginzip = null;
        byte[] compressed = null;
        String decompressed = null;
        try {
            compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
            in = new ByteArrayInputStream(compressed);
            ginzip = new GZIPInputStream(in);

            byte[] buffer = new byte[1024];
            int offset = -1;
            while ((offset = ginzip.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ginzip != null) {
                try {
                    ginzip.close();
                } catch (IOException e) {
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            try {
                out.close();
            } catch (IOException e) {
            }
        }
        return decompressed;
    }

    public static void main(String[] args) {
        
    }
}

spring boot 一定要扫描到AuditLogAspect.java

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring boot自定义注解拦截接口 的相关文章

随机推荐

  • linux下查看可执行文件的相关信息

    1 file 可执行文件 可查看可执行文件是ARM架构还是X86架构 2 nm 可执行文件 可查看文件中的符号 xff0c 包括全局变量 xff0c 全局函数等 3 ldd 可执行文件 可查看文件执行所需要的动态库 4 strings 可执
  • linux下查看系统内存使用情况的几个命令

    最近在客户现场运行的arm linux嵌入式设备出现了死机情况 xff0c 由于接触linux嵌入式设备时间不长 xff0c 遇到该问题后觉得束手无措 后领导提示说查看其他没有死机设备的系统资源使用情况 xff0c 下面介绍下我用到的那些命
  • Linux下获取CPUID、硬盘序列号

    在很多系统软件的开发中 xff0c 需要使用一些系统的唯一性信息 所以 xff0c 得到主机的CPUID 硬盘序列号及网卡的MAC地址 xff0c 就成个一件很重要的应用 需要的准备知识有 xff1a 1 GCC的嵌入汇编 xff0c 具体
  • Thinkpad MORFFHL滑鼠接收器配对

    1 接收器插入电脑 2 关闭鼠标 3 同时按住鼠标左键 右键 滚轮打开电源开关 xff0c 3个键按住3秒左右松手 4 同时按下3个按键 xff0c 指示灯橘色闪烁 5 再次同时按下3个按键 xff0c 配对结束 6 关闭鼠标重新打开 移动
  • Vbox6.04 Debian虚拟机安装增强工具

    环境 xff1a VBox6 04 Debian9 6 64位 在创建Vbox虚拟机后安装好Debian系统 开始操作前请确保虚拟机可以上网 1 root用户登录Debian xff1b 2 uname r 查看debian内核版本 3 a
  • Debian系统源码安装usb网卡驱动

    系统为debian 9 6 64位版本 xff0c 安装网卡驱动为asix的 AX88772B芯片 1 安装系统build模块 apt get install linux image uname r linux headers uname
  • Ubuntu根目录下各文件夹的作用

    Ubuntu上常识和常用命令 xff1a 1 Ubuntu文件结构 在ubuntu上硬盘的目录和Windows上不同 xff0c Windows可以根据自己的需求分不同的盘符 xff0c 但ubuntu上只有一个盘 xff0c 从根目录开始
  • linux中的export命令介绍

    export Linux中export命令介绍 xff0c 三种方法设置环境变量 CSDN博客
  • 一位 JavaScript 铁杆粉眼中的 Rust

    以下为译文 xff1a 我使用 Rust 编写了一些小工具 xff0c 而且觉得很有乐趣 我的日常工作需要大量使用 JavaScript xff0c 而 Rust 给我一种非常熟悉的感觉 xff0c 因此我决定尝试一下Rust 但与此同时
  • 树莓派3B+搭配Buster版本系统进行红外遥控开发

    一 配件清单 树莓派 xff1a 3B 43 系统版本 xff1a Buster红外接收器 xff1a VS1838B 红外遥控器 xff1a 未知型号 xff08 标有ar mp3字样 xff09 杜邦线若干 二 线路组合准备 根据网上查
  • Rust生态技术栈

    文章目录 Rust开发生态 开发整理 20230106更新 1 日志记录1 1 simple logger1 2 env logger 2 输入 输出3 String类型的match4 print 输出无效问题5 线程6 Excel读取7
  • Rust GUI方案调研

    GUI库方案 xff1a QT xff1a qt功能强大 xff0c 稳定 xff0c 如果功能比较复杂 xff0c 可以考虑qt绑定 orbtk xff1a rust语言编写的操作系统redox项目的GUI方案 xff0c 完全使用rus
  • windows远程Ubuntu(xrdp+vnc)步骤及问题解决方案(ip设置)

    首先将计算机连入相应的路由器 xff0c 登陆账号即可上网 xff0c 下面部分引用了blog xff1a http zhouxiaowei1120 github io Blogs 20160407 html 其中第 xff08 5 xff
  • Ubuntu/debian 中更改桌面的路径/位置

    虚拟机debian系统中安装好vmware tool 后 xff0c 系统的桌面变为了主目录 修改如下 xff1a vi config user dir dirs 把其中的 XDG DESKTOP DIR 61 HOME 改成如下 XDG
  • 八数码问题的可解性

    对于给定八数码棋局的初始状态 xff0c 我们的目标是通过交换空格与其相邻棋子使棋盘达到目标状态 其中 xff0c 游戏规则是只能交换空格与其上下左右四个方向的相邻棋子 假设棋局目标状态为如下形式 xff1a xff08 A B C D E
  • Powershell远程错误整理

    xfeff xfeff 错误现象 权限不够 xff1a 执行Set WSManQuickConfig Enable PSRemoting会报错 xff0c 用Get Item WSMan 检查时会发现其子项无法访问 xff0c 用reged
  • vs2013编译错误error: MSB8020,一招解决这个错误

    错误提示 xff1a error MSB8020 The build tools for v140 Platform Toolset 61 39 v140 39 cannot be found To build using the v140
  • CSP考试 2016年04月第3题 路径解析 C++实现

    表示本目录 xff0c 例如 d1 f1 指定的就是 d1 f1 如果有多个连续的 出现 xff0c 其效果等同于一个 绝对路径 xff1a 以 符号开头 xff0c 表示从根目录开始构建的路径 相对路径 xff1a 不以 符号开头 xff
  • bash环境中的通配符和特殊符号的简单介绍

    Bash环境中可以用通配符 wildcard 来更好的对数据进行处理 下面介绍一些常用的通配符 符号 意义 代表0个到无穷多个任意字符 代表一定有一个任意字符 代表一定有一个在中括号内得字符 非任意字符 例如 abcd 代表一定有一个字符
  • spring boot自定义注解拦截接口

    自定义注解 xff0c 拦截接口请求 maven依赖管理 span class token generics function span class token punctuation lt span dependency span cla