在SpringBoot中缓存HTTP请求响应体(实现请求响应日志的记录)

缓存请求响应体的目的把一个HTTP的请求,响应信息完整的纪录到日志。是一种常见有效的问题排查,BUG重现的手段。但是流这种东西,有一个特点就是只能读取/写入一次,不能重复。下一次读写,就是一个空的流,为了实现流的重用,就很有必要,把读取和写入的数据缓存起来, 可以在某个地方,再一次的读取。实现的思路HttpServletRequestWrapperHttpServletResponseWrapper上面2个类,熟悉Servlet的都知道,这俩就是Request和Response的装饰模式实
摘要由CSDN通过智能技术生成

缓存请求响应体的目的

把一个HTTP的请求,响应信息完整的纪录到日志。是一种常见有效的问题排查,BUG重现的手段。

但是这种东西,有一个特点就是只能读取/写入一次,不能重复。下一次读写,就是一个空的流,为了实现流的重用,就很有必要,把读取和写入的数据缓存起来, 可以在某个地方,再一次的读取。

实现的思路

  • HttpServletRequestWrapper
  • HttpServletResponseWrapper

上面2个类,熟悉Servlet的都知道,这俩就是RequestResponse的装饰模式实现。

通过装饰者设计模式,我们可以在Request读取请求body的时候,把读取到的数据复制一份缓存起来,记录日志时使用。同理,也可以把Response响应的数据,先缓存起来,用于记录日志,然后再响应给客户端。

Spring提供的实现

ContentCachingRequestWrapper

// 这里忽略了 HttpServletRequest 的相关方法
public class ContentCachingRequestWrapper extends HttpServletRequestWrapper  {
   
	// 包装Servlet,不限制请求体的大小
	public ContentCachingRequestWrapper(HttpServletRequest request)
	// 包装Servlet,限制请求体的大小
	public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit)
	// 获取到缓存的请求体
	public byte[] getContentAsByteArray()
	// 请求体超过限制时会调用这个方法,默认空实现
	protected void handleContentOverflow(int contentCacheLimit) 
}

比较好理解的一个类,建议通过contentCacheLimit限制请求体大小。因为它默认把请求体缓存到内存中,如果客户端发起恶意请求,构造大体积的请求体可能会消耗干净服务器的内存

ContentCachingResponseWrapper

// 这里忽略了 HttpServletResponse 的相关方法
public class ContentCachingResponseWrapper {
   
	// 把缓存中的响应数据,刷出到客户端
	void copyBodyToResponse()
	// 获取缓存数据
	byte[] getContentAsByteArray()
	// 获取缓存数据
	InputStream getContentInputStream()
	// 获取缓存数据的大小
	int getContentSize()
}

很简单,通过ContentCachingResponseWrapper的包装,任何往客户端的响应数据,都会被它缓存起来,重复的读取使用,最终响应给客户端

请求日志的实现

Controller

及其简单,把请求体,添加时间戳后回写给客户端。

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/demo"
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值