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

Spring Boot3迁移:TestRestTemplate调用HttpClient5报Target host空指针

Spring Boot 3迁移后TestRestTemplate集成测试报NullPointerException(Target host)问题解决

问题背景

从Spring Boot 2.x迁移到3.x后,原本正常的集成测试抛出NullPointerException: Target host错误。测试代码通过@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)启动随机端口服务,使用TestRestTemplate调用相对路径接口,调试确认TestRestTemplate已持有正确的主机URI(如http://localhost:64877),但执行时HttpClient5仍提示主机为null。项目依赖Apache HttpClient5,指定或不指定版本均无改善。

最终定位问题出在自定义的RestTemplateCustomizer中,使用HttpClients.createMinimal()初始化HttpClient:

@Bean
public RestTemplateCustomizer customRestTemplateCustomizer() {
    return new RestTemplateCustomizer() {
        @Override
        public void customize(RestTemplate restTemplate) {
            restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(HttpClients.createMinimal()));
            restTemplate.setErrorHandler(new ApiResponseErrorHandler());
        }
    };
}

移除setRequestFactory代码或改用HttpClients.createDefault()后,测试恢复正常。

原因分析

HttpClients.createMinimal()创建的是极简版HttpClient实例,仅保留最基础的HTTP执行能力,缺少两个关键组件:

  • 路由规划器(DefaultRoutePlanner):负责将相对路径与TestRestTemplate持有的基础URI拼接为完整请求地址
  • URI解析预处理逻辑:处理主机补全、路径合并等核心操作

而TestRestTemplate调用相对路径接口时,完全依赖HttpClient的路由机制自动补全完整URI。极简版HttpClient缺少这些组件,导致无法正确解析目标主机,最终抛出NullPointerException。

相比之下,HttpClients.createDefault()会初始化完整的客户端组件,包括路由规划器、连接池等,能够正常处理相对路径到完整URI的转换。

解决方案

方案1:改用createDefault()初始化HttpClient

保留自定义配置的同时,替换为具备完整能力的默认客户端:

@Bean
public RestTemplateCustomizer customRestTemplateCustomizer() {
    return restTemplate -> {
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault()));
        restTemplate.setErrorHandler(new ApiResponseErrorHandler());
    };
}

方案2:为极简版HttpClient手动添加路由规划器

如果确实需要使用极简客户端,手动配置DefaultRoutePlanner来支持URI解析:

@Bean
public RestTemplateCustomizer customRestTemplateCustomizer() {
    return restTemplate -> {
        HttpClient httpClient = HttpClients.custom()
                .setRoutePlanner(new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE))
                .build();
        restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
        restTemplate.setErrorHandler(new ApiResponseErrorHandler());
    };
}

方案3:移除自定义RequestFactory配置

如果不需要自定义HttpClient,直接删除setRequestFactory代码,使用Spring Boot自动配置的默认RequestFactory即可:

@Bean
public RestTemplateCustomizer customRestTemplateCustomizer() {
    return restTemplate -> {
        restTemplate.setErrorHandler(new ApiResponseErrorHandler());
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:35:20