1. 程式人生 > >Spring Boot 使用攔截器記錄使用者操作日誌

Spring Boot 使用攔截器記錄使用者操作日誌

前言

上篇檔案主要是講了如何使用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);
    }
}

專案結構如下

測試

編寫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");
    }
}

依次訪問:

專案原始碼

開源後臺管理系統

歡迎體驗Aurora