AOP slice programming records user operations and connects to the database

1. Pom.xml depends on importing

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

        <!--引入druid依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.14</version>
        </dependency>

        <!--Spring Boot Mybatis 依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

        <!-- MySQL 连接驱动依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>
        
       <!-- 这里我使用lombok生成getting和setting等方法,如果没安装插件的,可以不需要加这个 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
            <scope>provided</scope>
        </dependency>
        
        <!-- aop依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2. Log information entity class

Remember to configure the lombok plugin

@Getter
@Setter
@ToString
@Data
//系统日志管理
public class SystemLog {
    /**
    * 主键,标识列,自动生成
    */
    private Integer logid;

    /**
    * 关联员工表主键
    */
    private String empname;

    /**
    * Ip地址
    */
    private String ipaddr;

    /**
    * 操作时间
    */
    private Date optime;

    /**
    * 操作的内容
    */
    private String params;

    /**
    * 信息
    */
    private String msg;
}

3. SystemLogDao (Dao layer)

@Repository
@Transactional
public interface SystemLogDao {
	
	//保存日志信息到数据库
    int insert(SystemLog systemLog);

}

4. Create the mapper.xml file of the Dao layer

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.stodgy.dao.SystemLogDao">

  <insert id="insert" keyColumn="logId" keyProperty="logid" parameterType="com.stodgy.bean.SystemLog" useGeneratedKeys="true">
    <[email protected]>
    insert into systemLog (empName, ipAddr, optime,
      params, msg)
    values (#{empname,jdbcType=VARCHAR}, #{ipaddr,jdbcType=VARCHAR}, #{optime,jdbcType=TIMESTAMP},
      #{params,jdbcType=VARCHAR}, #{msg,jdbcType=VARCHAR})
  </insert>
</mapper>

5. Create a Service class

public interface SystemLogService {

   	int insert(SystemLog systemLog);
}


6. Create the ServiceImpl class

@Service
public class SystemLogServiceImpl implements SystemLogService {

    @Resource
    private SystemLogDao sd;

    @Override
    public int insert(SystemLog systemLog) {
        return sd.insert(systemLog);
    }

}

7. Create a custom annotation Log

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}

Eight, tool class IPUtils and HttpContextUtils

IPUtils

package com.atqh.logistics.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;


@Slf4j
public class IpUtils {

    /**
     * 获取IP地址
     * <p>
     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null, unknown = "unknown", seperator = ",";
        int maxLength = 15;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            log.error("IpUtils ERROR ", e);
        }

        // 使用代理,则获取第一个IP地址
        if (StringUtils.isEmpty(ip) && ip.length() > maxLength) {
            int idx = ip.indexOf(seperator);
            if (idx > 0) {
                ip = ip.substring(0, idx);
            }
        }

        return ip;
    }

    /**
     * 获取ip地址
     *
     * @return
     */
    public static String getIpAddr() {
        HttpServletRequest request = com.atqh.logistics.utils.HttpContextUtils.getHttpServletRequest();
        return getIpAddr(request);
    }
}

HttpContextUtils

public class HttpContextUtils {
    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
}

Nine, LogAspect class

@Aspect
@Component
public class LogAspect {

    @Autowired
    private SystemLogDao sd;

    @Pointcut("@annotation(com.ht.annotation.Log)")
    public void pointcut() { }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
        Object result = null;
        long beginTime = System.currentTimeMillis();
        try {
            // 执行方法
            result = point.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        // 保存日志
        saveLog(point, time);
        return result;
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SystemLog systemLog = new SystemLog();
        Log logAnnotation = method.getAnnotation(Log.class);
        if (logAnnotation != null) {
            //获取注解@Log在controller上的描述
            systemLog.setMsg(logAnnotation.value());
        }

        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        //获取session
        HttpSession session = request.getSession();
        // 设置IP地址
        systemLog.setIpaddr(IPUtils.getIpAddr(request));
       	//这里我是获取登录的用户,我已将登录的用户的信息放进了session
        //获取session的用户
        Emp emp = (Emp)session.getAttribute("emp");
        systemLog.setEmpname(emp.getEmpname());
        //设置登录时间
        systemLog.setOptime(new Date());
        //设置登录参数
        systemLog.setParams(emp.toString());

        // 保存系统日志
        sd.insert(systemLog);
    }
}

10. Use in the Controller class that needs to be monitored

@Controller
@RequestMapping("/login")
public class LoginController {

    @Resource
    private LoginService ls;
    
    //在每个方法前加,当访问这个方法的时候,就会自动去保存你已经设置好的日志信息
    @Log("登录系统")
    //查询是否该员工账号
    @RequestMapping("/isnEmp")
    @ResponseBody
    public Map isnEmp(Emp emp, HttpSession session){
        Emp login = ls.login(emp);
        Map map = new HashMap();
        if (login!=null){
            session.setAttribute("emp",login);
            map.put("i",1);
        }
        return map;
    }

    //退出登录
    @RequestMapping("/out")
    public String out(HttpSession session){
        session.removeAttribute("emp");
        return "login";
    }
}

Guess you like

Origin blog.csdn.net/weixin_64443786/article/details/130916868