• SpringBoot下,@WebFilter配置获取日志



    CREATE TABLE [dbo].[SWEBSERVICELOG]( [WLG_ID] [varchar](100) NOT NULL, [WLG_SESSIONID] [varchar](100) NULL, [WLG_REMOTEIPADDR] [varchar](20) NULL, [WLG_REQUESTURL] [varchar](100) NULL, [WLG_START_DT] [datetime2](7) NULL, [WLG_END_DT] [datetime2](7) NULL, [WLG_CLIENTHOST] [varchar](200) NULL, [WLG_USERAGENT] [varchar](500) NULL, [WLG_METHOD] [nvarchar](20) NULL, [WLG_PARAMS] [varchar](500) NULL, [WLG_PARAMSVALUE] [varchar](4000) NULL, [WLG_RETURN_MSG] [text] NULL, [WLG_EXCEPTION] [varchar](500) NULL, [WLG_CREATION_DT] [datetime] NULL, [WLG_UPDATE_DT] [datetime] NULL, [WLG_CREATIONUID] [varchar](50) NULL, [WLG_UPDATEUID] [varchar](50) NULL, [WLG_NAME] [varchar](100) NULL, [WLG_RETURN_CODE] [varchar](20) NULL, [WLG_RETURN_MESSAGE] [varchar](200) NULL, [WLG_SOURCE] [varchar](20) NULL, CONSTRAINT [SWEBSERVICELOG_WECHAT_WLG_ID_pk_4] PRIMARY KEY CLUSTERED ( [WLG_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO

      

    package cn.com.acxiom.coty.wechat.ws.filter;
    
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.io.UnsupportedEncodingException;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.Date;
    import java.util.UUID;
    import java.util.regex.Pattern;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ReadListener;
    import javax.servlet.ServletException;
    import javax.servlet.ServletInputStream;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.WriteListener;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    
    import cn.com.acxiom.coty.wechat.ws.bean.po.WebserviceLogWechat;
    import cn.com.acxiom.coty.wechat.ws.common.CONST;
    import cn.com.acxiom.coty.wechat.ws.common.ResponseBean;
    import cn.com.acxiom.coty.wechat.ws.common.UUID16;
    import cn.com.acxiom.coty.wechat.ws.mapper.WebserviceLogWechatMapper;
    import com.alibaba.fastjson.JSONObject;
    import org.apache.commons.io.IOUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    
    import org.springframework.util.StringUtils;
    
    
    
    @SuppressWarnings("ALL")
    @WebFilter
    @Component("logFilter")
    public class LogFilter implements Filter {
    
    
        static InetAddress ia = null;
    
        static {
            try {
                ia = InetAddress.getLocalHost();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    
        private static final Logger logger = LoggerFactory.getLogger(LogFilter.class);
        private static final String NOTLOGIN = "NOT LOGIN";
        private static final String LOGIN_PATH = "/account";
    
        @Autowired
        private WebserviceLogWechatMapper webLogMapper;
    
        @Value("${sys.name}")
        private String sysName;
    
        private Pattern ignore = Pattern.compile(".*/webjars/.*$|.*/v2/.*$|.*/swagger.*$|.*/configuration/.*$|.*/images/.*|.*/farvirate.ico|.*/actuator.*");
    
        static final Pattern BLANK = Pattern.compile("\t|
    |
    ");
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    
            long startTime = System.currentTimeMillis();
    
    
            /* 判断如果是swagger界面请求的一些资源就不会走日志 */
            HttpServletRequest request = (HttpServletRequest) req;
    
            if ("option".equalsIgnoreCase(request.getMethod())){
                System.out.println("OPTION");
            }
    
            HttpServletResponse response = (HttpServletResponse) res;
            String requestId = null;
    
            if (StringUtils.isEmpty(request.getHeader("sid"))) {
                requestId = UUID.randomUUID().toString().replace("-", "");
                request.setAttribute("sid", requestId);
            } else {
                requestId = request.getHeader("sid");
                request.setAttribute("sid", request.getHeader("sid"));
            }
            response.addHeader("sid", requestId);
    
    
            String requestURL = request.getRequestURI();
            if (ignore.matcher(requestURL).matches()) {
                chain.doFilter(req, res);
                return;
            }
    
    
            // 2、RequestBody读取
            // 创建包装对象
            LoggerHttpServletRequest wrappedRequest = new LoggerHttpServletRequest(request);
            // 读取参数
            String content = IOUtils.toString(wrappedRequest.getInputStream());
            // 重设参数
            wrappedRequest.resetServletInputStream();
            // 返回输出值
            wrappedRequest.setAttribute("sid", requestId);
            OutputStream outputStream = res.getOutputStream();
    
            LoggerHttpServletResponse wrapperResponse = new LoggerHttpServletResponse(response);
    
            chain.doFilter(wrappedRequest, wrapperResponse);
    
            long endTime = System.currentTimeMillis();
            byte[] responseContent = wrapperResponse.getData();
            String responseContext = null;
            String responseContentType = wrapperResponse.getContentType();
            if (!StringUtils.isEmpty(responseContentType) && responseContentType.contains("image")) {
                responseContext = "[image]";
            } else {
                responseContext = new String(wrapperResponse.getData(), "UTF-8");
            }
    
            outputStream.write(responseContent);
    
            /* 插入接口参数捕获日志 */
            try {
                insertWebServiceInvokeLog(wrappedRequest, wrapperResponse, responseContext, content, startTime, endTime, requestId);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    
        private void insertWebServiceInvokeLog(LoggerHttpServletRequest wrappedRequest, LoggerHttpServletResponse wrapperResponse, String responseBody, String requestBody, long beginTime,
                                               long endTime, String requestId) {
            String httpMethod = wrappedRequest.getMethod();
            String remoteHost = wrappedRequest.getRemoteHost();
            String params = wrappedRequest.getQueryString();
            String userAgent = wrappedRequest.getHeader("user-agent");
            String requestPath = wrappedRequest.getServletPath();
            String responseContentType = wrapperResponse.getContentType();
            String apiName =wrapperResponse.getHeader(CONST.RESPONS_API_NAME_KEY);
    
    
            // 创建系统日志
            WebserviceLogWechat webLog = new WebserviceLogWechat();
    
            webLog.setWlgId(UUID16.uuid());
            webLog.setWlgCreationuid(sysName);
            webLog.setWlgCreationDt(new Date());
            webLog.setWlgUpdateDt(new Date());
            webLog.setWlgUpdateuid(sysName);
            webLog.setWlgRemoteipaddr(remoteHost);
            webLog.setWlgRequesturl(requestPath);
    
            webLog.setWlgStartDt(new Date(beginTime));
            webLog.setWlgEndDt(new Date(endTime));
            webLog.setWlgMethod(httpMethod);
            webLog.setWlgName(apiName);
            webLog.setWlgParams(params);
            webLog.setWlgParamsvalue(requestBody);
    
            webLog.setWlgReturnMsg(responseBody);
    
            try {
                if (!StringUtils.isEmpty(responseContentType) && !responseContentType.contains("image")) {
                    ResponseBean responseBean = JSONObject.parseObject(responseBody, ResponseBean.class);
                    webLog.setWlgReturnMessage(responseBean.getMessage());
                    webLog.setWlgReturnCode(responseBean.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
            webLog.setWlgUseragent(userAgent);
            webLog.setWlgClienthost(String.format("%s:%s", ia.getHostName(), ia.getHostAddress()));
            webLog.setWlgSessionid(requestId);
            webLog.setWlgSource(sysName);
    
            try {
                webLogMapper.insertSelective(webLog);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("requestId:[{}] Save log to db with some error",requestId);
                logger.error("requestId:[{}] Save log to file, Log Data: ",requestId, JSONObject.toJSONString(webLog));
            }
    
    
        }
    
    
        /**
         * 包装HttpServletRequest
         */
        private static class LoggerHttpServletRequest extends HttpServletRequestWrapper {
    
            private byte[] data;
            private HttpServletRequest request;
            private LoggerServletInputStream servletInputStream;
    
            public LoggerHttpServletRequest(HttpServletRequest request) {
                super(request);
                this.request = request;
                servletInputStream = new LoggerServletInputStream();
            }
    
            public void resetServletInputStream() {
                try {
                    servletInputStream.inputStream = new ByteArrayInputStream(new String(data).getBytes("UTF-8"));
                } catch (UnsupportedEncodingException e) {
    
                    logger.error(e.getMessage());
    
                }
            }
    
            @Override
            public ServletInputStream getInputStream() throws IOException {
                if (data == null) {
                    data = IOUtils.toByteArray(this.request.getReader());
                    servletInputStream.inputStream = new ByteArrayInputStream(data);
                }
                return servletInputStream;
            }
    
            private class LoggerServletInputStream extends ServletInputStream {
    
                private InputStream inputStream;
    
                @Override
                public int read() throws IOException {
                    return inputStream.read();
                }
    
                @Override
                public boolean isFinished() {
                    return false;
                }
    
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public void setReadListener(ReadListener listener) {
    
                }
    
            }
        }
    
        /**
         * 包装的HttpServletResponse类
         *
         * @author jacwan
         */
        private static class LoggerHttpServletResponse extends HttpServletResponseWrapper {
    
            private ByteArrayOutputStream byteStream;
    
            public LoggerHttpServletResponse(HttpServletResponse response) {
                super(response);
                byteStream = new ByteArrayOutputStream();
            }
    
            @Override
            public ServletOutputStream getOutputStream() {
                return new LoggerServletOutputStream(byteStream);
            }
    
            @Override
            public PrintWriter getWriter() throws IOException {
                return new PrintWriter(getOutputStream(), false);
            }
    
            public byte[] getData() {
                return byteStream.toByteArray();
            }
    
            public class LoggerServletOutputStream extends ServletOutputStream {
    
                private DataOutputStream dataOutputStream;
    
                public LoggerServletOutputStream(OutputStream output) {
                    dataOutputStream = new DataOutputStream(output);
                }
    
                @Override
                public void write(int b) throws IOException {
                    dataOutputStream.write(b);
                }
    
                @Override
                public void write(byte[] b) throws IOException {
                    dataOutputStream.write(b);
                }
    
                @Override
                public void write(byte[] b, int off, int len) throws IOException {
                    dataOutputStream.write(b, off, len);
                }
    
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public void setWriteListener(WriteListener listener) {
    
                }
            }
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void destroy() {
        }
    }
    

      1. 需要注意的是: 实现的接口Filter是javax.servlet包中的,不是util.logger中的

      2. 有时候需要在运行的main函数头上加上@ServletComponentScan,有时候不需要添加, @WebFilter的使用还要深入看下,如果在filter类的头上加上@Component("小写的filter类名"),就可以不用添加@ServletComponentScan

    直接上测试代码

    DemoApplication中

    package com.example.demo;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    @SpringBootApplication
    @EnableCaching
    @EnableTransactionManagement
    @EnableAsync
    public class DemoApplication implements CommandLineRunner {
    
        private static Logger logger = LoggerFactory.getLogger(DemoApplication.class);
    
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            logger.info("started");
            System.out.println("startedstartedstartedstartedstarted====");
        }
    }
    

      

    ResponseBean
    package com.example.demo.pojo;
    
    import com.example.demo.common.Message;
    import com.fasterxml.jackson.annotation.JsonIgnore;
    
    public class ResponseBean<T> {
    
        @JsonIgnore
        public boolean ok() {
            return this.code.equalsIgnoreCase(Message.SUCCESS_CODE);
        }
    
        public ResponseBean() {
            this.code = Message.SUCCESS_CODE;
            this.message = Message.SUCCESS_MESSAGE;
        }
    
        public ResponseBean(T data) {
            this.code = Message.SUCCESS_CODE;
            this.message = Message.SUCCESS_MESSAGE;
            this.data = data;
        }
    
        private T data;
        private String code;
        private String message;
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }
    

      

    IndexController
    package com.example.demo.controller;
    
    
    import com.example.demo.pojo.ResponseBean;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    
    @RestController
    public class IndexController {
    
        @GetMapping("/index")
        public ResponseBean index(){
            ResponseBean responseBean = new ResponseBean();
            String info = "=========Welcome===========";
            responseBean.setData(info);
            return responseBean;
        }
    
    
    }
    
    Message
    package com.example.demo.common;
    
    public class Message {
    
        public static final String SUCCESS_CODE = "0000";
        public static final String SUCCESS_MESSAGE = "success";
    
    }
    

     

    FilterDemo01
    package com.example.demo.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    
    @WebFilter
    @Component("filterDemo01")
    public class FilterDemo01 implements Filter {
    
    
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("----FilterDemo01过滤器初始化----");
        }
    
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
            // 对request和response进行一些预处理
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
    
            System.out.println("FilterDemo01执行前!!!");
            chain.doFilter(request, response); // 让目标资源执行,放行
            System.out.println("FilterDemo01执行后!!!");
        }
    
    
        public void destroy() {
            System.out.println("----过滤器销毁----");
        }
    
    
    }
    

     

    Rest0PubFilter
    package com.example.demo.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    @WebFilter
    @Component
    //(urlPatterns = "/*", filterName = "rest0PubFilter")
    //@Order(1)//指定过滤器的执行顺序,值越大越靠后执行
    public class Rest0PubFilter implements Filter {
    
    
        @Override
        public void init(FilterConfig filterConfig) {//初始化过滤器
            System.out.println("getFilterName:"+filterConfig.getFilterName());//返回<filter-name>元素的设置值。
            System.out.println("getServletContext:"+filterConfig.getServletContext());//返回FilterConfig对象中所包装的ServletContext对象的引用。
            System.out.println("getInitParameter:"+filterConfig.getInitParameter("cacheTimeout"));//用于返回在web.xml文件中为Filter所设置的某个名称的初始化的参数值
            System.out.println("getInitParameterNames:"+filterConfig.getInitParameterNames());//返回一个Enumeration集合对象。
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                             FilterChain filterChain) throws IOException, ServletException {
            if(false){
                //response.sendRedirect("http://localhost:8081/demo/test/login");//重定向
                System.out.println("==========");
            }
            filterChain.doFilter(servletRequest, servletResponse);//doFilter将请求转发给过滤器链下一个filter , 如果没有filter那就是你请求的资源
    
        }
    
        @Override
        public void destroy() {
        }
    
    }
    

      启动程序的时候

     调用接口

     

      

  • 相关阅读:
    SQL exists( select 1 from
    svn不知道这样的主机
    SVN 操作指南
    SVN导出/导入、SVN备份/还原 【小白版】
    Asp.net窄屏页面 手机端新闻列表
    装饰者模式
    适配器模式
    原型模式
    建造者模式
    抽象工厂方法
  • 原文地址:https://www.cnblogs.com/qianjinyan/p/11133940.html
Copyright © 2020-2023  润新知