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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:55:10