Spring Boot 使用拦截器记录用户操作日志

时间:2024-04-14 08:03:31

前言

上篇文件主要是讲了如何使用aop记录用户操作日志,这篇文件将介绍如何使用拦截器记录操作日志

导入依赖

在处理请求参数时需要用到Json,其他依赖请查看源码

<!-- Json解析 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.31</version>
</dependency>

部分配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/log
    username: root
    password: 123456

  jpa:
    hibernate:
      ddl-auto: update

创建实体类

@Entity
@Data
@Table(name = "zj_syslog")
public class SysLog implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String url;

    private Integer time;

    private String method;

    private String params;

    private String ip;

    /**
     * ip地址来源
     */
    private String location;

    @CreationTimestamp
    private Timestamp createTime;
}

创建 repository

@Repository
public interface SysLogRepo extends JpaRepository<SysLog,Long>{
}

自定义日志拦截器

public class LogInterceptor implements HandlerInterceptor {
    //请求开始时间标识
    private static final String LOGGER_SEND_TIME = "_send_time";
    //请求日志实体标识
    private static final String LOGGER_ENTITY = "_logger_entity";

    /**
     * 进入SpringMVC的Controller之前开始记录日志实体
     * @param request 请求对象
     * @param response 响应对象
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {

        //创建日志实体
        SysLog sysLog = new SysLog();

        //获取请求参数信息
        String param = JSON.toJSONString(request.getParameterMap(),
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteMapNullValue);

        //设置请求参数
        sysLog.setParams(param);

        // 设置IP地址
        sysLog.setIp(AddressUtils.getIpAddr(request));

        sysLog.setLocation(AddressUtils.getCityInfo(sysLog.getIp()));

        //设置请求方法,GET,POST...
        sysLog.setMethod(request.getMethod());

        //设置请求路径
        sysLog.setUrl(request.getRequestURI());

        //设置请求开始时间
        request.setAttribute(LOGGER_SEND_TIME,System.currentTimeMillis());

        //设置请求实体到request内,方便afterCompletion方法调用
        request.setAttribute(LOGGER_ENTITY,sysLog);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        int status = httpServletResponse.getStatus();

        //根据不同状态码,跳转不同页面,如
        if(status==404){
            modelAndView.setViewName("/404");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {

        //得到bean
        SysLogRepo sysLogRepo = SpringContextUtils.getBean("sysLogRepo",SysLogRepo.class);

        //获取请求错误码,根据需求存入数据库,这里不保存
        int status = response.getStatus();

        //当前时间
        long currentTime = System.currentTimeMillis();

        //请求开始时间
        long time = Long.valueOf(request.getAttribute(LOGGER_SEND_TIME).toString());

        //获取本次请求日志实体
        SysLog sysLog = (SysLog) request.getAttribute(LOGGER_ENTITY);

        //设置访问者
        sysLog.setUsername("admin");

        //设置请求时间差
        sysLog.setTime(Integer.valueOf((currentTime - time)+""));

        //执行将日志写入数据库,可以根据实际需求进行保存
        if(!sysLog.getMethod().equals("GET")){

        }
        sysLogRepo.save(sysLog);
    }
}

新增ConfigurerAdapter

新增ConfigurerAdapter类,实现WebMvcConfigurer接口

重写addInterceptors方法,添加我们的拦截器


@Configuration
public class ConfigurerAdapter implements WebMvcConfigurer {

    //设置排除路径,spring boot 2.*,注意排除掉静态资源的路径,不然静态资源无法访问
    private final String[] excludePath = {"/list"};

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /**
         * 添加日志的拦截器
         */
        registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**").excludePathPatterns(excludePath);
    }
}

项目结构如下

Spring Boot 使用拦截器记录用户操作日志

测试

编写TestController


@RestController
public class TestController {

    @Autowired
    private SysLogRepo sysLogRepo;

    @GetMapping(value = "/test")
    public String test1(String test){

        return test;
    }

    @GetMapping(value = "/list")
    public ModelAndView list(Model model){

        List<SysLog> sysLogs = sysLogRepo.findAll();
        model.addAttribute("sysLogs",sysLogs);

        return new ModelAndView("/index");
    }
}

依次访问:

localhost:8080/test?test=123

Spring Boot 使用拦截器记录用户操作日志

localhost:8080/list

Spring Boot 使用拦截器记录用户操作日志

项目源码

github:https://github.com/dqjdda/SpringBoot_All

码云:https://gitee.com/hgpt/SpringBoot_All

开源后台管理系统

欢迎体验Aurora

github: https://github.com/dqjdda/Aurora

码云: https://gitee.com/hgpt/Aurora