RestTemplate调用外部API返回JSON响应被截断问题求助
Spring Boot中RestTemplate调用外部API返回JSON被截断的解决办法
在Spring Boot项目中,通过Controller使用RestTemplate调用外部API获取数据并返回时,偶尔会出现JSON响应末尾被截断的情况。尝试过自定义RestTemplate、调整application.yaml中的响应大小配置,问题仍未解决。以下是相关代码、截断示例及配置,附可行解决方向:
相关代码与配置
Controller代码
@GetMapping(value = "/weather/lat={lat}&lon={lon}") @Cacheable(value = "root", key = "{#lat , #lon}") public ResponseEntity<Root> getWeather(@PathVariable("lat") String lat, @PathVariable("lon") String lon) { try{ String request = String.format("%s?lat=%s&lon=%s&units=metric&appid=%s", weatherUrl, lat, lon, appId); return restTemplate.getForEntity(request, Root.class); }catch (RestClientException e){ return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } }
截断的JSON示例
{ "coord": { "lat": 1.4, "lon": 2.33 }, "weather": [ { "id": 804, "main": "Clouds", "description": "overcast clouds", "icon": "04n" } ], "base": "stations", "main": { "temp": 26.15, "feels_like": 26.15, "temp_min": 26.15, "temp_max": 26.15, "pressure": 1014, "humidity": 79, "sea_level": 1014, "grnd_level": 1014 }, "visibility": 10000, "wind": { "speed": 6.34, "deg": 198, "gust": 6.08 }, "clouds": { "all": 100 }, "dt": 1696111416, "sys": { "sunrise": 1696052261, "sunset": 1696095829 }, "timezone": 0, "id": 0, "name":"co
application.yaml配置
spring: application: name: weather-service servlet: multipart: max-file-size: 10MB max-request-size: 10MB boot: admin: client: instance: api-gateway-port: 17957 management-base-url: http://localhost:${spring.boot.admin.client.instance.api-gateway-port} eureka: instance: instance-id: ${spring.application.name}:${random.value} client: serviceUrl: defaultZone: http://localhost:8888/eureka/ appid: ********************* url: external-api: weather: https://api.openweathermap.org/data/2.5/weather server: port: 0
可行解决方向
1. 调整RestTemplate消息转换器缓冲区
默认的MappingJackson2HttpMessageConverter可能存在缓冲区大小限制,自定义RestTemplate时手动设置更大缓冲区:
@Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); for (HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) { if (converter instanceof MappingJackson2HttpMessageConverter) { ((MappingJackson2HttpMessageConverter) converter).setBufferSize(1024 * 1024); // 设置1MB缓冲区 break; } } return restTemplate; }
2. 手动读取响应体再转换
绕过RestTemplate自动转换逻辑,先完整读取响应字符串,再手动序列化为对象,避免转换器中途截断:
@GetMapping(value = "/weather/lat={lat}&lon={lon}") @Cacheable(value = "root", key = "{#lat , #lon}") public ResponseEntity<Root> getWeather(@PathVariable("lat") String lat, @PathVariable("lon") String lon) { try{ String request = String.format("%s?lat=%s&lon=%s&units=metric&appid=%s", weatherUrl, lat, lon, appId); ResponseEntity<String> rawResponse = restTemplate.getForEntity(request, String.class); ObjectMapper objectMapper = new ObjectMapper(); Root root = objectMapper.readValue(rawResponse.getBody(), Root.class); return ResponseEntity.ok(root); }catch (Exception e){ return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } }
3. 检查缓存是否存储截断数据
由于使用了@Cacheable,若首次请求时响应已被截断,后续会直接返回缓存的不完整数据。可先清除缓存,测试新请求是否正常;或调整缓存序列化配置,确保完整存储对象。
4. 验证外部API响应完整性
用Postman、curl等工具直接请求目标API的相同URL,确认返回的原始JSON是否完整。若外部API本身存在响应截断问题,需联系服务商或添加不完整响应的容错处理。
5. 调整Spring MVC响应缓冲区
在application.yaml中添加Spring MVC响应缓冲区配置:
spring: servlet: response: buffer-size: 1048576 # 设置1MB响应缓冲区
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

