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|\r|\n"); @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() {
} }

  启动程序的时候

 调用接口

 

  

SpringBoot下,@WebFilter配置获取日志的更多相关文章

  1. SpringBoot下如何配置实现跨域请求?

    一.什么是跨域请求? 跨域请求,就是说浏览器在执行脚本文件的ajax请求时,脚本文件所在的服务地址和请求的服务地址不一样.说白了就是ip.网络协议.端口都一样的时候,就是同一个域,否则就是跨域.这是由 ...

  2. springboot下slf4j配置

    我们在引用的时候直接写 private static final Logger logger = LoggerFactory.getLogger(XXXServiceImpl.class); log. ...

  3. springboot下@webfilter的使用

    启动类加了@ServletComponentScan,无论过滤器类加不加@Componment urlPatterns = {"/test/*"}都可以生效 单使用@Compone ...

  4. SpringBoot优雅地配置日志

    本文主要给大家介绍SpringBoot中如何通过sl4j日志组件优雅地记录日志.其实,我们入门 JAVA 的第一行代码就是一行日志,那你现在还在使用System.out.println("H ...

  5. springboot 通过@WebFilter(urlPatterns )配置Filter过滤路径

    springboot 通过@WebFilter(urlPatterns )配置Filter过滤路径,没有配置/*,输入任何路径都能进过滤器 2019年04月25日 12:51:33 peigui.hu ...

  6. SpringBoot下Druid连接池的使用配置

    Druid是一个JDBC组件,druid 是阿里开源在 github 上面的数据库连接池,它包括三部分: * DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体 ...

  7. JAVAEE——SpringBoot日志篇:日志框架SLF4j、日志配置、日志使用、切换日志框架

    Spring Boot 日志篇 1.日志框架(故事引入) 小张:开发一个大型系统: ​ 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件 ...

  8. Centos下Nginx配置WEB访问日志并结合shell脚本定时切割

    在一个成熟的WEB系统里,没有日志管理是不可以的,有了日志,可以帮助你得到用户地域来源.跳转来源.使用终端.某个URL访问量等相关信息:通过错误日志,你可以得到系统某个服务或server的性能瓶颈等. ...

  9. SpringBoot | 第四章:日志配置(转)

    前言 介于平时工作中,对于日志这块没有过多的接触,也就未有过多的了解.故在编写本文时,上官网查看了相关资料,奈何每个字母我都认识,但合起来就有点晕了,英文阅读水平还是有待大大的提高呀.最后觉得还是转载 ...

随机推荐

  1. 【Leetcode_easy】868. Binary Gap

    problem 868. Binary Gap solution1: class Solution { public: int binaryGap(int N) { ; vector<int&g ...

  2. WXS --注释

  3. 《ucore lab5》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 加载应用程序并执行(需要编码) 题目 do_execv函数调用load_icode(位于kern/process/proc.c中) 来 ...

  4. java junit4-JUnit测试报 No socket available 错误

    问题描述 JUnit测试报 No socket available 错误 Eclipse进行JUnit测试时,总弹出 No socket available 窗口,导致测试不能进行. 解决方案一: 打 ...

  5. [DevExpress] - 使得 XtraEditors.TextEdit 失去焦点(LostFocus)的方法

    场景 WinForm 应用,使用了 DevExpress.XtraEditors.TextEdit 控件的 KeyPress 和 Leave 事件.期望在 TextEdit 上按下回车键或者当 Tex ...

  6. 创建线程的三种方式(Thread、Runnable、Callable)

    方式一:继承Thread类实现多线程: 1. 在Java中负责实现线程功能的类是java.lang.Thread 类. 2. 可以通过创建 Thread的实例来创建新的线程. 3. 每个线程都是通过某 ...

  7. Linux基础-14-ssh服务、apache服务

    1. ssh服务 ssh服务是一个守护进程(demon),系统后台监听客户端的连接,ssh服务端的进程名为sshd,负责实时监听客户端的请求(IP 22端口),包括公共秘钥等交换等信息. ssh服务端 ...

  8. PAT甲级题分类汇编——杂项

    本文为PAT甲级分类汇编系列文章. 集合.散列.数学.算法,这几类的题目都比较少,放到一起讲. 题号 标题 分数 大意 类型 1063 Set Similarity 25 集合相似度 集合 1067 ...

  9. MySQL8.0新特性总览

    1.消除了buffer pool mutex (Percona的贡献) 2.数据字典全部采用InnoDB引擎存储,支持DDL原子性.crash safe.metadata管理更完善(可以利用ibd2s ...

  10. webpack css文件编译、自动添加前缀、剥离

    1.css文件编译 webpack默认只能编译js文件,引入css需要loader支持 // css文件写入js中 npm i style-loader -D // css文件loader npm i ...