前后端联调拦截器日志打印配置

打印信息格式:

前端信息

后端信息

springboot下配置

import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Configuration
public class LoggingFilterConfig implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(LoggingFilterConfig.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        Map<String, Object> map = new HashMap<String, Object>();
        HttpServletRequest requestWrapper = null;

        // LogPosition使用时间戳作为日志的定位数字,在idea的控制台中使用Ctrl+f调出查询框,
        // 让前端将异常接口的LogPosition发给后端,后端即可快速定位错误接口
        String time = String.valueOf(new Date().getTime());
        res.setHeader("LogPosition",time);
        map.put("LogPosition",time);

        try {
            // Get request URL.
            map.put("URL", req.getRequestURL());
            map.put("Method", req.getMethod());
            map.put("Protocol", req.getProtocol());
            map.put("RemoteAddr", req.getRemoteAddr());
            map.put("RemoteHost", req.getRemoteHost());

            // 获取header信息
            List<Map<String, String>> headerList = new ArrayList<>();
            Map<String, String> headerMaps = new HashMap<>();
            for (Enumeration<String> enu = req.getHeaderNames(); enu.hasMoreElements(); ) {
                String name = enu.nextElement();
                headerMaps.put(name, req.getHeader(name));
            }
            headerList.add(headerMaps);
            map.put("Headers", headerList);

            //获取parameters信息
            List<Map<String, String>> parameterList = new ArrayList<>();
            Map<String, String> parameterMaps = new HashMap<>();
            for (Enumeration<String> names = req.getParameterNames(); names.hasMoreElements(); ) {
                String name = names.nextElement();
                parameterMaps.put(name, req.getParameter(name));
            }
            parameterList.add(parameterMaps);
            map.put("parameters", parameterList);

            // 获取请求体信息,一般为json,此处慎用,传输文件时ContentType不包含multipart报跨域
            // 其它情况暂未发现,如发现一直报错未解决,可以先把这两个日志拦截处理文件先删除
            String reqContentType = req.getContentType();
            HashMap<Object, Object> contextMap = new HashMap<>();
            System.out.println(reqContentType);
            if (reqContentType != null){
                if (!reqContentType.contains("multipart")){
                    requestWrapper = new RepeatedlyReadRequestWrapper(req);
                    String line = "";
                    if (req.getMethod().equalsIgnoreCase("POST")) {
                        int len = req.getContentLength();
                        char[] buf = new char[len];
                        int bufcount = requestWrapper.getReader().read(buf);
                        if (len > 0 && bufcount <= len) {
                            line = String.copyValueOf(buf).substring(0, bufcount);
                        }
                    } else if (req.getMethod().equalsIgnoreCase("GET")) {
                        int idx = req.getRequestURL().indexOf("?");
                        if (idx != -1) {
                            line = req.getRequestURL().substring(idx + 1);
                        } else {
                            line = null;
                        }
                    }
                    if (line != null) {
                        contextMap.put("Context", new String[]{line});
                    }
                }
            }

            //打印日志信息
            JSONObject context = JSONObject.fromObject(contextMap);
            String strContext = context.toString();
            String substring = "";
            if(strContext.length() >= 14){
                substring = context.toString().substring(12, strContext.length() - 2);
            }

            System.out.println();
            logger.info("URL:" + map.get("URL"));
            logger.info("LogPosition:" + map.get("LogPosition"));
            logger.info("RemoteHost:" + map.get("RemoteHost"));
            logger.info("Method:" + map.get("Method"));
            logger.info(substring);
            //这里输出一个回车的作用是便于复制Context的json,在浏览器搜索json找一个在线解析json的网站,复制丢进去
            System.out.println();
            if (requestWrapper == null){
                chain.doFilter(request, response);
            }else {
                chain.doFilter(requestWrapper, response);
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void destroy() {

    }
}

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

public class RepeatedlyReadRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;

    public RepeatedlyReadRequestWrapper(HttpServletRequest request)
            throws IOException {
        super(request);
        body = readBytes(request.getReader(), "UTF-8");
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);
        return new ServletInputStream() {

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }

            @Override
            public int read() {
                return bais.read();
            }
        };
    }

    /**
     * 通过BufferedReader和字符编码集转换成byte数组
     */
    private byte[] readBytes(BufferedReader br, String encoding) throws IOException {
        String str = null, retStr = "";
        while ((str = br.readLine()) != null) {
            retStr += str;
        }
        //StringUtil.isNotNull可以自己实现也可以用第三方或自带的,其作用是判断入参是否为空串
        if (StringUtil.isNotNull(retStr)) {
            return retStr.getBytes(Charset.forName(encoding));
        }
        return null;
    }
}
发布了43 篇原创文章 · 获赞 12 · 访问量 9864

猜你喜欢

转载自blog.csdn.net/OrangeHap/article/details/103522494