项目脚手架——日志打印重构
重构前

日志记录使用Spring Interceptor拦截器来统一记录,我们的预期是打印出请求的详细信息,包括 traceId,请求头,请求体,响应头,响应体。
使用 ThreadLocal 帮助保存响应信息和请求开始时间,方便对请求时间进行统计。
使用请求包装类来包装HttpServletRequest,因为请求内容是以输入流的形式存在,只能读取一次,所以使用包装类来复制流的内容并存到字节数组中。
问题:
1、如果请求在到达记录日志的Interceptor之前发生了错误,将直接返回且不会记录日志。比如请求在验证权限的 LoginInterceptor 被拦截,将不会达到记录日志的 LogInterceptor。这对问题排查造成了一定的阻碍。
2、使用比较多的 ThreadLocal,使得代码有些耦合,不够优雅。
重构

1、将日志打印放到 Filter 来做,避免不会记录日志的问题。
2、使用装饰器设计模式,对 HttpServletRequest 和 HttpServletResponse 进行扩展,使得我们可以多次获取到请求内容和响应内容,并且不需要使用ThreadLocal,日志相关的代码不会放到其他类中,遵循类的单一职责原则。
3、Filter不能设置排除路径,自定义 ExcludePathFilter 类对 GenericFilterBean 进行包装增强,不需要每次在 doFilter 方法内判断路径并跳过。