Spring Boot RestTemplate调用外部API返回null空指针问题求助
问题原因
空指针的直接诱因是rest.getForObject()返回了null,和JSON映射、自定义类写法没有关系。
你能正常调用restcountries的测试接口,是因为该接口没有做客户端校验;而巴西彩票的官方接口加了请求拦截规则:RestTemplate默认发请求时携带的User-Agent是Java版本标识(类似Java/1.8.0_333),目标服务识别到是非浏览器的爬虫/脚本请求,会直接返回403状态或者空响应体,默认配置的RestTemplate遇到这类响应不会抛异常,而是直接返回null,后续调用toString()就触发了空指针。
排查验证步骤
- 把
getForObject换成exchange方法获取完整响应对象,先打印响应状态码,你会看到返回的不是200,而是403 Forbidden - 可以用curl做对照测试:带默认Java UA发请求拿不到结果,换成浏览器UA就能正常返回JSON,和上述逻辑一致
修复代码
给请求加上模拟浏览器的请求头,同时加状态校验避免空指针,参考如下实现:
import org.springframework.http.*; import org.springframework.web.client.RestTemplate; import java.util.Collections; @GetMapping(value = "/loterias") public String getLotteryResults() { String url = "http://servicebus2.caixa.gov.br/portaldeloterias/api/home/ultimos-resultados"; RestTemplate restTemplate = new RestTemplate(); // 构造模拟浏览器的请求头 HttpHeaders headers = new HttpHeaders(); headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36"); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); HttpEntity<Void> request = new HttpEntity<>(headers); // 发送请求获取完整响应 ResponseEntity<String> response = restTemplate.exchange( url, HttpMethod.GET, request, String.class ); // 校验响应状态后再返回结果 if (response.getStatusCode().is2xxSuccessful()) { return response.getBody(); } return "接口请求失败,状态码:" + response.getStatusCode(); }
额外注意事项
- 要获取原始JSON字符串直接用
String.class作为响应类型即可,不需要先转Object再调用toString(),避免序列化环节出问题 - 后续要映射自定义响应类,只需要把exchange方法的响应类型参数换成你的目标类就行,请求通的前提下映射不会有问题
- 正式环境不要每次请求都新建RestTemplate实例,把它配置成Spring管理的单例Bean注入使用,合理配置连接池参数提升性能
内容的提问来源于stack exchange,提问作者asdiasx
相关产品推荐
相关产品推荐

