HttpServletRequest对象获取body(多次)

1,100 阅读1分钟

在网关层或者HandlerInterceptor 层,对请求body进行处理的时候,默认的request是不能多次获取的. 我们可以使用ContentCachingRequestWrapper ,它是 Spring 提供的一个类,主要用于缓存 HTTP 请求的内容。当你使用这个类时,它会将请求体(body)缓存起来,以便你可以多次读取。

具体来说,ContentCachingRequestWrapper 允许你通过以下方式多次获取请求体:

  1. 第一次读取:当你第一次调用 getContentAsByteArray()getContentAsString() 方法时,请求体会被读取并缓存。
  2. 后续读取:之后,你可以再次调用这些方法,依然能获取到缓存的请求体,而不会抛出异常或导致读取失败。

解析代码如下:

    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();
    }