基于4.1.7.RELEASE

Filter处理request log的基类,提供了在filterChain.doFilter调用前后的回调函数,其实现类有CommonsRequestLoggingFilter,Log4jNestedDiagnosticContextFilter,ServletContextRequestLoggingFilter。

其核心代码为doFilterInternal方法:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {boolean isFirstRequest = !isAsyncDispatch(request);HttpServletRequest requestToUse = request;if (isIncludePayload() && isFirstRequest && !(request instanceof ContentCachingRequestWrapper)) {requestToUse = new ContentCachingRequestWrapper(request);}boolean shouldLog = shouldLog(requestToUse);if (shouldLog && isFirstRequest) {beforeRequest(requestToUse, getBeforeMessage(requestToUse));}try {filterChain.doFilter(requestToUse, response);}finally {if (shouldLog && !isAsyncStarted(requestToUse)) {afterRequest(requestToUse, getAfterMessage(requestToUse));}}
}

在调用filterChain.doFilter方法前后分别调用beforeRequest和afterRequest,而这两个方法具体实现由子类决定,根据功能不同来决定记录日志的方法,

在beforeRequest中和afterRequest中分别调用了  getBeforeMessage,getAfterMessage,这两个方法代码如下

private String getBeforeMessage(HttpServletRequest request) {return createMessage(request, this.beforeMessagePrefix, this.beforeMessageSuffix);
}private String getAfterMessage(HttpServletRequest request) {return createMessage(request, this.afterMessagePrefix, this.afterMessageSuffix);
}

最终都会进入到createMessage中去,只是前缀后缀不同,

before的Msg格式是: Before request [  Msg  ]

after的Msg格式是 : After request [  Msg  ]

这里的Msg具体内容则由createMessage决定

protected String createMessage(HttpServletRequest request, String prefix, String suffix) {StringBuilder msg = new StringBuilder();msg.append(prefix);msg.append("uri=").append(request.getRequestURI());if (isIncludeQueryString()) {msg.append('?').append(request.getQueryString());}if (isIncludeClientInfo()) {String client = request.getRemoteAddr();if (StringUtils.hasLength(client)) {msg.append(";client=").append(client);}HttpSession session = request.getSession(false);if (session != null) {msg.append(";session=").append(session.getId());}String user = request.getRemoteUser();if (user != null) {msg.append(";user=").append(user);}}if (isIncludePayload() && request instanceof ContentCachingRequestWrapper) {ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;byte[] buf = wrapper.getContentAsByteArray();if (buf.length > 0) {int length = Math.min(buf.length, getMaxPayloadLength());String payload;try {payload = new String(buf, 0, length, wrapper.getCharacterEncoding());}catch (UnsupportedEncodingException e) {payload = "[unknown]";}msg.append(";payload=").append(payload);}}msg.append(suffix);return msg.toString();
}

根据具体的参数设置的不同,其表现出不同的形式,msg的最基本格式为

Before/After request [  uri=xxx  ]

设置includeQueryString=true:

Before/After request [  uri=xxx?a=xx&b=xxx  ]

设置includeClientInfo=true:

Before/After request [  uri=xxx?a=xxx&b=xxx;client=xxx;session=sessionId;user=xxx  ]

设置includePayload=true:

先判断request的content的长度,如果超过设置maxPayload的长度,则按照maxPayload进行截取,如果出现异常,则payload=[unknown]

Before/After request [  uri=xxx?a=xxx&b=xxx;client=xxx;session=sessionId;user=xxx;payload=xxx/[unknown]  ]

下面来看其子类对应的不同的实现

CommonsRequestLoggingFilter:
@Override
protected boolean shouldLog(HttpServletRequest request) {return logger.isDebugEnabled();
}@Override
protected void beforeRequest(HttpServletRequest request, String message) {logger.debug(message);
}@Override
protected void afterRequest(HttpServletRequest request, String message) {logger.debug(message);
}

其主要是调用初始化时候设置的GenericFilterBean中的logger进行记录。

Log4jNestedDiagnosticContextFilter:

其采用了Log4j来进行日志记录。自定义变量

protected final Logger log4jLogger = Logger.getLogger(getClass());

ServletContextRequestLoggingFilter:

使用ServletContext来记录日志

Spring-web源码解析之Filter-AbstractRequestLoggingFilter相关推荐

  1. spring boot 源码解析23-actuate使用及EndPoint解析

    前言 spring boot 中有个很诱人的组件–actuator,可以对spring boot应用做监控,只需在pom文件中加入如下配置即可: <dependency><group ...

  2. 深入剖析Spring Web源码(十九) - 整理的文档和日志的索引(第一版)

    整理的文档 把所有的<深入剖析Spring Web>系列日志整理成为文档,供大家下载阅读,希望对大家有所帮助.里面有些章节尚未完成,所以称为第一版.希望不久的将来,能把没有完成的章节在第二 ...

  3. spring事务源码解析

    前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...

  4. Spring AOP源码解析-拦截器链的执行过程

    一.简介 在前面的两篇文章中,分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在得到了 bean 的代理对象,且通知也以合适的方式插在了目标方 ...

  5. Spring Session源码解析

    AbstractHttpSessionApplicationInitializer,很明显它是一个初始化的类,它是一个抽象类,可以理解为一个公用的基类,然后看一下onStartup这个方法,最主要的方 ...

  6. Spring MVC源码解析——HandlerMapping(处理器映射器)

    Sping MVC 源码解析--HandlerMapping处理器映射器 1. 什么是HandlerMapping 2. HandlerMapping 2.1 HandlerMapping初始化 2. ...

  7. Spring IOC源码解析笔记

    小伙伴们,你们好,我是老寇 Spring最重要的概念就算IOC和AOP,本篇主要记录Spring IOC容器的相关知识,本文适合有spring相关基础并且想了解spring ioc的相关原理的人看 本 ...

  8. Spring AOP源码解析(一)——核心概念

    目录 Pointcut ClassFilter MethodMatcher Advisor IntroductionAdvisor PointcutAdvisor AbstractPointcutAd ...

  9. Spring @Import源码解析

    在Spring boot中常用到@Import,允许通过它引入 @Configuration 注解的类 (java config), 引入ImportSelector接口(这个比较重要, 因为要通过它 ...

  10. Spring AOP源码解析——AOP动态代理原理和实现方式

    2019独角兽企业重金招聘Python工程师标准>>> Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和 ...

最新文章

  1. 475. Heaters
  2. mysql数据库主从配置
  3. 边工作边考研的计算机经验,边工作边考研的经验
  4. Servlet的认识
  5. spark性能优化 -- spark工作原理
  6. JVM运行时数据区分析
  7. PAT甲级 -- 1090 Highest Price in Supply Chain (25 分)
  8. 计算机操作系统 内存_计算机内存的类型| 操作系统
  9. 寻路的几种算法_Godot游戏开发实践之二:AI之寻路新方式
  10. NBIA Data Retriever(NBIA数据下载工具)使用
  11. Oracle根据月份获取其是哪个季度
  12. centos7 pe系统安装_U盘PE启动安装Win7系统教程(微PE版)
  13. php fpm过多,Linux下php-fpm进程过多导致内存耗尽问题解决
  14. 个人博客系统(附源码)
  15. 最通俗易懂的JavaScript入门教程
  16. treetable怎么带参数_jquery treeTable插件使用细则
  17. 使用 SetProcessWorkingSetSize 降低程序内存
  18. c#winform——Gobang五子棋简易版双人对战制作(基本结构+代码)
  19. linux表示一序列ip,linux 下查看硬件信息(mac,IP地址,硬盘型号,序列号等)
  20. 字节跳动智力题-推理题

热门文章

  1. 题解 P2949 【[USACO09OPEN]工作调度Work Scheduling】
  2. spring总结(01)
  3. 【leetcode-74】搜索二维矩阵
  4. 当安装软件后提示依赖没有安装时
  5. part01.04 事件
  6. weblogic hibernate HqlToken
  7. 不使用第三个变量交换两个变量
  8. 新云网站管理系统最新版注入漏洞
  9. Java笔记(三)内部类,容器,泛型和类型安全的容器,迭代器
  10. 七夕关爱单身狗程序猿:4本书给你一个完整的脱单秘籍