zoukankan      html  css  js  c++  java
  • SpringAop之日志管理

    导入的依赖均为JavaWeb界面在线配置代码生成器这篇文章,你只需将这篇文章的maven依赖导入即可。

    SpringAop利用注解的特性进行日志管理,只需在对应的方法上加上自己编写的注解,即可完美实现日志管理。

    日志管理的目的是,将后台管理人员,安卓人员,第三方人员每天请求的url和是谁操作的,在哪操作,使用什么系统操作,输入的那些参数,使用什么请求等等统统记录下来。方便异常排查和应对外来的web攻击。

    关于Controller和spring-mvc.xml使用了shiro,关于shiro方面可以参考我的如下文章,进行学习:

    MP实战系列(九)之集成Shiro

    shiro实战系列

    步骤如下:

    一、编写注解类

    package com.anotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface SysLog {
        
        String type() default "";//日志类型
        String action() default "";//作用
        String method() default "";//请求方式
    
    }

    二、编写Aspect

    package com.anotation;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.lang.reflect.Method;
    import java.math.BigDecimal;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import com.baomidou.mybatisplus.mapper.EntityWrapper;
    import com.entity.SysCompany;
    import com.entity.SysUser;
    import com.service.SysCompanyService;
    import com.service.SysLogService;
    import com.service.SysUserService;
    
    import cn.hutool.core.date.DateUtil;
    import cn.hutool.system.HostInfo;
    import cn.hutool.system.OsInfo;
    import cn.hutool.system.SystemUtil;
    
    
    
    public class SysLogAspect {
    
        @Autowired
        private SysLogService sysLogService;
        
        @Autowired
        private SysUserService userService;
        
        @Autowired
        private SysCompanyService companyService;
    
        /**
         * 环绕通知
         * 
         * @param joinPoint
         * @return
         * @throws Throwable
         */
        public Object aroud(ProceedingJoinPoint joinPoint) throws Throwable {
    
            // 开始时间
            long beginTime = System.currentTimeMillis();
    
            // 执行目标方法
            Object result = joinPoint.proceed();
    
            // 执行时长(毫秒)
            long time = System.currentTimeMillis() - beginTime;
    
            // 保存日志
            saveSysLog(joinPoint, time);
            
            return result;
        }
    
        /**
         * 保存日志
         * 
         * @param joinPoint
         * @param time
         */
        private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            
            SysLog sysLog = method.getAnnotation(SysLog.class);
            
            com.entity.SysLog log = new  com.entity.SysLog();
            
            HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            
            //获取session
            String userCode = (String) request.getSession().getAttribute("userCode");
            
            //获取用户信息
            EntityWrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
            wrapper.eq("user_code", userCode);
            SysUser user = userService.selectOne(wrapper);
            
            //获取公司信息
            EntityWrapper<SysCompany> wrapper2 = new EntityWrapper<SysCompany>();
            wrapper2.eq("company_code", user.getCorpCode());
            SysCompany company = companyService.selectOne(wrapper2);
     
                
                if (sysLog != null) {
                    
                    HostInfo hostInfo = SystemUtil.getHostInfo();
                    OsInfo osInfo = SystemUtil.getOsInfo();
                    log.setLogType(sysLog.type());
                    log.setLogTitle(sysLog.action());
                    log.setRequestMethod(sysLog.method());
                    log.setRequestUri(request.getRequestURI());
                    log.setRemoteAddr(request.getRemoteAddr());
                    log.setDeviceName(osInfo.getName());
                    log.setBrowserName(request.getHeader("User-Agent"));
                    log.setRequestParams(request.getQueryString());
                    log.setCreateBy(user.getUserName());
                    log.setCreateByName(user.getUserName());
                    log.setCreateDate(DateUtil.date().toString());
                    log.setServerAddr(hostInfo.getAddress());
                    log.setExecuteTime(BigDecimal.valueOf(time));
                    log.setIsException("否");
                    log.setCorpCode(company.getCorpCode());
                    log.setCorpName(company.getCompanyName());
                    
                }  
                // 保存系统日志
                sysLogService.insert(log);
    
        }
        
        
        
       
          
    
    }

    三、在spring-mvc.xml配置aop

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
            http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">
        <aop:aspectj-autoproxy />
        <!-- Controller包(自动注入) -->
        <context:component-scan base-package="com.controller"/>
    
        <!-- 将 springSwaggerConfig加载到spring容器 -->  
        <bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />  
    
        <mvc:default-servlet-handler/>
        
        <bean class="com.listener.InitDataListener"/>  
    
         <!-- FastJson注入 -->
        <mvc:annotation-driven>
            <mvc:message-converters register-defaults="true">
         
                <bean id="fastJsonHttpMessageConverter"
                      class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                         
                            <value>text/html;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        <!-- 上传限制 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 上传文件大小限制为31M,31*1024*1024 -->
            <property name="maxUploadSize" value="32505856"/>
        </bean>
        
        <!-- shiro 验证注解start -->
            <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
            <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
        
            <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
                <property name="proxyTargetClass" value="true" />
            </bean>
        
            <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
                <property name="securityManager" ref="securityManager"/>
            </bean>
        
        <!-- 异常处理 -->
       <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
                    <prop key="org.apache.shiro.authz.UnauthorizedException">/error/unauthorized</prop>
                    <prop key="org.apache.shiro.authz.UnauthenticatedException">/error/unlogined</prop>
                </props>
            </property>
        </bean>
         
    
     
     <!-- 切面 -->
    <bean id="sysLogAspect" class="com.anotation.SysLogAspect"></bean>
    
    <aop:config>
        <aop:aspect ref="sysLogAspect">
            <aop:pointcut expression="@annotation(com.anotation.SysLog)" id="sysLogPointcut"/>
            <aop:around method="aroud" pointcut-ref="sysLogPointcut"/>
        </aop:aspect>
    </aop:config>
    </beans>

    四、在对应的Controller方法上加上注解即可

    /**
         * 账号登录
         * @param request
         * @return
         */
        @PostMapping(value = "/login",produces="application/json;charset=utf-8")
        @SysLog(type="后台系统",action="登录功能",method="POST")
        @ApiOperation(value="登录",httpMethod="POST",notes="登录")
        public JSONObject login(@RequestParam String username, @RequestParam String password, HttpSession session,HttpServletResponse response) {
            //接收前台参数
            logger.info("用户名:"+username);
            logger.info("密码:"+password);
            //调用查询逻辑
            EntityWrapper<SysUser> wrapper = new EntityWrapper<SysUser>();
            wrapper.eq("login_code", username);
            SysUser user = userService.selectOne(wrapper);
            
            JSONObject json = new JSONObject();
            
            if(user != null && "0".equals(user.getStatus())) {
                //获取当前用户
                Subject subject = SecurityUtils.getSubject();  
                
                //根据前台传的用户名和密码进行认证
                UsernamePasswordToken token = new UsernamePasswordToken(username, password);         
          
                try {
                    //认证通过
                    subject.login(token); 
                
                    String encode = Base64.encode(user.getUserCode());
                    
                    //Cookie有效期默认为8小时
                    int time=28800;
                    
                    //将Cookie加密为16进制字符串
                    CookieUtils.setCookie(response,  "userCode", encode, time);
    
                    user.setLastLoginDate(DateUtil.date());
                    userService.updateById(user);
                    
                    //将userCode放入session中保存
                    session.setAttribute("userCode", user.getUserCode());
                    
                    json.put("token", subject.getSession().getId());
                    json.put(CommonEnum.RETURN_CODE, "000000");
                    json.put(CommonEnum.RETURN_MSG, "登录成功");
                } catch (IncorrectCredentialsException e) {
                    json.put(CommonEnum.RETURN_CODE, "111111");
                    json.put(CommonEnum.RETURN_MSG, "用户名或密码错误");
                }catch (Exception e) {
                    json.put(CommonEnum.RETURN_CODE, "222222");
                    json.put(CommonEnum.RETURN_MSG, "特殊异常");
                }
            }else {
                json.put(CommonEnum.RETURN_CODE, "500");
                json.put(CommonEnum.RETURN_MSG, "用户不存在");
            }    
            
            return json;
    
        }
  • 相关阅读:
    考试
    aws代理
    ansible debug
    apollo docker 安装 使用镜像 idoop/docker-apollo
    java jvm 内存监控工具visualvm 的使用
    kong dashboard UI 的使用 (使用kong 对服务反向代理,以及解决跨域问题)
    git账号
    kong Gateway && PostgreSQL 的安装(docker)
    apollo 配置中心的安装与使用
    springboot 开发模式 dev
  • 原文地址:https://www.cnblogs.com/youcong/p/9531852.html
Copyright © 2011-2022 走看看