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. web端自动化——selenium测试报告生成、找到测试报告路径、实现发邮件(整合)

    有这样的一个场景: 假设生成的测试报告与多人相关,每个人都去测试服务器査看就会比较麻烦,如果把这种主动的且不及时的査看变成被动且及时的査收,就方便多了. 整个程序的执行过程可以分为三个步骤: ①    ...

  2. Nginx配置文件的反向代理

    问题描述:项目需要预览pdf,前端控件支持的格式是http://192.168.0.1/pdf/a.pdf  是这样的,然后我就想给路径配个nginx反向代理就好了,但是配置的时候出问题了. 1.正确 ...

  3. Input.GetMouseButtonDown 在fixedupdate中会出现丢失问题,在update中则完全没这个问题

    Input.GetMouseButtonDown 在fixedupdate中会出现丢失问题,在update中则完全没这个问题

  4. 【VS开发】windows下的signal

    在windows下,信号机制简单来说是通过工作线程实现的,该线程运行于相对优先级THREAD_PRIORITY_HIGHEST,当信号产生时,windows生成该线程执行信号处理逻辑,由于该线程优先级 ...

  5. 【GStreamer开发】GStreamer基础教程01——Hello World

    目标 对于一个软件库来说,没有比在屏幕上打印出Hello World更近直观的第一印象了.因为我们是在和一个多媒体的framework打交道,所以我们准备播放一段视频来代替Hello World.不要 ...

  6. yarn 的常用命令

    初始化新项目yarn init添加依赖包yarn add [package]yarn add [package]@[version]yarn add [package]@[tag]将依赖项添加到不同依 ...

  7. Django之用户注册

    用户注册需要提交的信息包括: 用户名 邮箱 密码 确认密码 验证码 这里选择form表单提交信息,注册页面的响应函数就要分条件执行,get请求时要展示注册页面,post请求时要接收用户提交的信息,对信 ...

  8. Linux【Ubuntu】安装docker

    内核要大于3.10才能安装docker 查看内核 uname -r 安装yum命令 sudo apt install yum 由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改,故添加使用 ...

  9. JIRA+JIRA Agile敏捷项目管理工具

    jira插件下载地址 http://www.confluence.cn/pages/viewpage.action?pageId=1671327 下载GreenHopper插件 安装Jira-agil ...

  10. SQL语言的分类(DQL、DML、DDL、DCL的概念与区别)

    SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL. 1. 数据查询语言DQL数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHER ...