在Jooby框架的Java环境中能否多次访问request.body?
解决Jooby框架中多次读取request.body()为空的问题
嘿,这个问题我熟!你遇到的情况是因为Jooby默认不会缓存请求体——请求体本质是一个输入流,第一次调用request.body()的时候已经把流读完了,第二次再读自然就拿不到内容了,所以才会出现Second: None的输出。
下面给你两种场景的解决方案:
1. 单个路由内多次使用请求体
最简单的办法就是只读取一次请求体,然后复用这个对象,代码改成这样:
// 只读取一次body,存到变量里 Mutant body = request.body(); log.info("First: {}, Second: {}", body, Strings.isNullOrEmpty(body.value()) ? "None": body.value() );
这样不管你用多少次body变量,都是用的第一次读取到的内容,不会出现空值。
2. 多个路由/拦截器间共享请求体
如果需要在同一个请求的不同路由、拦截器里多次读取请求体,就得让Jooby缓存请求体内容。你可以通过两种方式配置:
全局启用缓存
在你的应用类里全局开启请求体缓存,这样所有路由都能多次读取body:
{ // 全局配置BodyParser启用缓存 parser((parser, config) -> parser.cache(true)); // 之后任意路由里都能多次调用request.body() post("/test", req -> { Mutant first = req.body(); Mutant second = req.body(); log.info("First: {}, Second: {}", first, Strings.isNullOrEmpty(second.value()) ? "None": second.value() ); return "OK"; }); }
针对单个路由启用缓存
如果不想全局开启,只给特定路由启用缓存:
{ post("/specific-endpoint", req -> { Mutant first = req.body(); Mutant second = req.body(); // 处理逻辑 return "Success"; }).parser(p -> p.cache(true)); // 给这个路由单独启用缓存 }
手动缓存请求体
另外,你也可以手动把读取到的body存到请求属性里,在同一个请求的其他地方取用:
// 第一次读取时存入请求属性 Mutant body = request.body(); request.attribute("cachedRequestBody", body); // 在同一个请求的其他组件(比如拦截器、后续路由)里获取 Mutant cachedBody = request.attribute("cachedRequestBody");
这样就能完美解决多次读取request.body()为空的问题啦!
内容的提问来源于stack exchange,提问作者Vera
相关产品推荐
相关产品推荐

