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

RestAssured调用Spring认证接口时请求体为空导致401问题

解决RestAssured调用Spring接口时请求体为空的问题

我之前也踩过一模一样的坑!结合你的描述——RestAssured发的POST JSON请求明明已经通过ngrep确认发送成功,但Spring拦截器里拿到的请求体是空,用curl/Postman却完全正常,大概率是以下几个原因之一,给你逐个排查的方向:

1. 确认RestAssured的请求体构建是否正确

很多时候是因为没正确使用body()方法传参,比如误用了params()(这是传表单参数的)。正确的JSON请求写法应该是:

// 方式1:直接传序列化后的JSON字符串
given()
    .contentType(ContentType.JSON)
    .body("{\"username\":\"test\",\"password\":\"123456\"}")
.when()
    .post("/api/auth")
.then()
    .log().all();

// 方式2:传Java对象,让RestAssured自动序列化(依赖Jackson)
AuthRequestDto authRequest = new AuthRequestDto("test", "123456");
given()
    .contentType(ContentType.JSON)
    .body(authRequest)
.when()
    .post("/api/auth")
.then()
    .log().all();

如果是用对象序列化,要确保项目里有jackson-databind依赖,并且RestAssured能自动识别到它(最新版本的RestAssured默认集成Jackson,但如果依赖冲突可能会失效)。

2. 检查Spring拦截器/过滤器的请求体读取逻辑

HTTP请求体只能被读取一次,如果你的认证拦截器/过滤器在Spring解析@RequestBody之前,直接用request.getInputStream()或request.getReader()读取了请求体,那后续Spring就拿不到数据了。

解决办法是用Spring提供的ContentCachingRequestWrapper包装请求,它会把请求体缓存起来,支持重复读取:

public class AuthFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 包装请求,缓存请求体
        ContentCachingRequestWrapper cachedRequest = new ContentCachingRequestWrapper(request);
        
        // 这里读取缓存的请求体做认证逻辑
        byte[] requestBody = cachedRequest.getContentAsByteArray();
        if (requestBody.length > 0) {
            String bodyStr = new String(requestBody, cachedRequest.getCharacterEncoding());
            // 处理认证逻辑
        }
        
        // 用包装后的请求继续传递
        filterChain.doFilter(cachedRequest, response);
    }
}

记得在Spring配置里注册这个过滤器,替换原来的直接读取请求体的逻辑。

3. 排查RestAssured的全局配置是否覆盖了请求头

有时候全局配置会意外覆盖请求的contentType设置,比如不小心设置了:

RestAssured.defaultParser = Parser.TEXT;

这会导致RestAssured默认不按JSON解析请求体。解决办法是在单个请求里显式指定contentType和accept:

given()
    .contentType(ContentType.JSON)
    .accept(ContentType.JSON)
    .body(authRequest)
.when()
    .post("/api/auth")

4. 检查Spring的消息转换器配置

如果你的Spring项目自定义了HttpMessageConverter,要确保MappingJackson2HttpMessageConverter没有被移除,它是Spring解析JSON请求体的核心转换器。可以在配置类里确认:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 不要移除默认的Jackson转换器,或者手动添加
        converters.add(new MappingJackson2HttpMessageConverter());
        // 其他自定义转换器...
    }
}

最后可以加个调试小技巧:在Spring的拦截器里打印请求的Content-Type头和缓存的请求体,确认请求头是否正确,以及请求体是否真的为空——有时候只是读取方式不对,不是真的没收到。

内容的提问来源于stack exchange,提问作者mik3fly-4steri5k

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:12:31