在网关层或者HandlerInterceptor 层,对请求body进行处理的时候,默认的request是不能多次获取的.
我们可以使用ContentCachingRequestWrapper ,它是 Spring 提供的一个类,主要用于缓存 HTTP 请求的内容。当你使用这个类时,它会将请求体(body)缓存起来,以便你可以多次读取。
具体来说,ContentCachingRequestWrapper 允许你通过以下方式多次获取请求体:
- 第一次读取:当你第一次调用
getContentAsByteArray()或getContentAsString()方法时,请求体会被读取并缓存。 - 后续读取:之后,你可以再次调用这些方法,依然能获取到缓存的请求体,而不会抛出异常或导致读取失败。
解析代码如下:
public static String getParamAndVal(final HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
boolean hasFile = request instanceof MultipartHttpServletRequest;
if (hasFile) {
sb.append("file=>")
.append("...")
.append("|");
}
String queryString = request.getQueryString();
if (StringUtils.isNotBlank(queryString)) {
sb.append("qs=>")
.append(queryString)
.append("|");
}
String body = "";
final ContentCachingRequestWrapper requestToUse = (ContentCachingRequestWrapper) (!(request instanceof ContentCachingRequestWrapper) ? new ContentCachingRequestWrapper(request) : request);
try {
if (!hasFile && requestToUse.getContentAsByteArray().length < MAX_BODY_SIZE) {
body = new String(requestToUse.getContentAsByteArray(), requestToUse.getCharacterEncoding());
}
} catch (UnsupportedEncodingException ignored) {
}
if (StringUtils.isNotBlank(body)) {
sb.append(" _body=>")
.append(body)
.append("|");
}
return sb.toString();
}