You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus中如何通过ContainerRequestContext获取请求体

Quarkus LoggingFilter获取请求体实现方案

可以从ContainerRequestContext中获取请求体内容,但要注意Servlet规范中请求体对应的输入流仅支持读取一次,如果直接在过滤器中读取后不做回写,后续业务接口将无法正常获取请求参数,具体实现方式如下:

  • 提前过滤不需要读取请求体的场景:GET/DELETE等无请求体的方法、multipart/form-data类型的文件上传请求直接跳过,避免不必要的性能损耗和内存溢出风险。
  • 从上下文获取原始输入流,读取指定长度的字节内容转换为字符串格式的请求体。
  • 将读取到的字节内容重新封装为字节输入流,调用setEntityStream()方法回写到请求上下文中,保证后续业务流程可以正常读取请求参数。

改造后的过滤器代码示例

@Provider
public class LoggingFilter implements ContainerRequestFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingFilter.class);
    // 限制最大读取的请求体长度为1M,避免大请求撑爆内存
    private static final int MAX_BODY_CACHE_LENGTH = 1024 * 1024;

    @Inject
    JsonWebToken jwt;

    @Context
    UriInfo uriInfo;

    @Context
    HttpServerRequest request;


    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        String method = requestContext.getMethod();
        String path = uriInfo.getPath();
        String address = request.remoteAddress().toString();
        String operator = jwt.getName();
        String requestBody = "";

        // 跳过无请求体方法、文件上传类请求
        MediaType requestType = requestContext.getMediaType();
        if (!("GET".equalsIgnoreCase(method) || "DELETE".equalsIgnoreCase(method))
                && requestType != null
                && !requestType.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) {
            InputStream originStream = requestContext.getEntityStream();
            byte[] bodyBytes = originStream.readNBytes(MAX_BODY_CACHE_LENGTH);
            requestBody = new String(bodyBytes, StandardCharsets.UTF_8);
            // 回写输入流,不影响后续接口参数解析
            requestContext.setEntityStream(new ByteArrayInputStream(bodyBytes));
        }

        LOGGER.info("{}:{}, From {}, By {}, RequestBody: {}", method, path, address, operator, requestBody);
    }
}

额外提示:如果不需要高度自定义日志格式,Quarkus REST/RESTEasy Reactive已经内置了请求响应日志能力,只需要在配置文件中添加quarkus.rest.logging.enabled=true即可自动开启,内置实现已经处理了流复用、大请求截断等问题,性能比手写过滤器更优。

内容的提问来源于stack exchange,提问作者Hydra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:06:18