在SpringBoot中利用过滤器实现请求日志的记录

package com.zhizhiyun.filter;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.zhizhiyun.exam.domain.entity.Record;
import com.zhizhiyun.utils.RecordUtils;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 需要注意的是,所有的请求,都会进过滤器哦。
 */
@Component
public class AuditFilter extends HttpFilter {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        ContentCachingRequestWrapper cachingRequestWrapper = new ContentCachingRequestWrapper(httpRequest);
        ContentCachingResponseWrapper cachingResponseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);
        // 执行请求链
        super.doFilter(cachingRequestWrapper, cachingResponseWrapper, chain);
        if (httpRequest.getRequestURI().startsWith("/admin/")) {// 所有请求都会进来,所以这里直接进行请求地址的判断,只对/admin的请求地址进行审计日志记录
            String params;
            if ("POST".equalsIgnoreCase(httpRequest.getMethod()) && "application/json".equalsIgnoreCase(httpRequest.getContentType())) {
                params = new String(cachingRequestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
            } else {
                params = JSONObject.toJSONString(httpRequest.getParameterMap());
            }
            if (StpUtil.isLogin() && jdbcTemplate != null) {
                Record record = RecordUtils.httpToRecord(httpRequest, StpUtil.getLoginIdAsString());
                jdbcTemplate.update(
                        "INSERT INTO `t_sys_record` (`user_id`, `cdate`, `dopath`, `remote_addr`, `method`, `params`, `user_agent`) VALUES (?, ?, ?, ?, ?, ?, ?)",
                        record.getUserId(),
                        record.getCdate(),
                        record.getDopath(),
                        record.getRemoteAddr(),
                        record.getMethod(),
                        params,
                        record.getUserAgent()
                );
            }
        }
        // 这一步很重要,把缓存的响应内容,输出到客户端
        cachingResponseWrapper.copyBodyToResponse();
    }
}
package com.zhizhiyun.utils;

import com.zhizhiyun.exam.domain.entity.Record;
import jakarta.servlet.http.HttpServletRequest;

import java.io.IOException;

public class RecordUtils {

    public static Record httpToRecord(HttpServletRequest request, String loginIdAsString) throws IOException {
        Record record = new Record();
        record.setCdate(DateUtil.now());
        record.setUserId(loginIdAsString);
        record.setRemoteAddr(IPUtil.getIpAddr(request));
        record.setUserAgent(request.getHeader("user-agent"));
        record.setDopath(request.getRequestURI());
        record.setMethod(request.getMethod());
        return record;
    }
}

 

发布者:songJian   点击数:216   发布时间:2024-04-17 10:53:46   更新时间:2024-04-17 10:56:13
正在加载评论...
相关文章