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

使用Spring Rest Template无法将API响应序列化为自定义类

问题解决:API响应反序列化为NewsDTO时属性全为null

问题根源

从你提供的API响应结构来看,返回的JSON并非直接的新闻数组,而是一个包含data字段的外层对象,data字段内部才是你需要的新闻列表数组。你当前直接将整个响应反序列化为List<NewsDTO>,Jackson无法匹配到对应的字段映射,因此每个NewsDTO的属性都为null。

解决方案

1. 创建响应包装类

先定义一个与API返回结构匹配的包装类,用来接收完整的响应:

@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class NewsResponse implements Serializable {
    // 对应API响应中的data字段,内部是新闻列表
    private List<NewsDTO> data;
}

2. 修改反序列化逻辑

在控制器中,先将响应解析为包装类实例,再提取其中的新闻列表:

@RestController
public class StockApiController {
    @Value("${api.key}")
    private String apikey;
    
    @GetMapping("/news")
    public List<NewsDTO> getStockNews() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        // 若API不会返回单个对象替代数组,可移除该配置
        // mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

        String newsUri = "https://yahoo-finance15.p.rapidapi.com/api/v1/markets/news";
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        httpHeaders.set("X-RapidAPI-Key", apikey);
        httpHeaders.set("X-RapidAPI-Host", "yahoo-finance15.p.rapidapi.com");

        HttpEntity request = new HttpEntity(httpHeaders);

        String response = restTemplate.exchange(newsUri, HttpMethod.GET, request, String.class).getBody();

        // 先解析为包装类,再提取data中的新闻列表
        NewsResponse newsResponse = mapper.readValue(response, NewsResponse.class);
        List<NewsDTO> newsDTOList = newsResponse.getData();

        return newsDTOList;
    }
}

备选方案:使用JsonPath直接提取数据

如果你不想创建包装类,可以引入JsonPath依赖,直接从响应中提取data字段的内容:

  1. 添加Maven依赖:
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.8.0</version>
</dependency>
  1. 修改反序列化代码:
List<NewsDTO> newsDTOList = JsonPath.parse(response)
        .read("$.data", new TypeReference<List<NewsDTO>>() {});

验证要点

  • 确保NewsDTO的属性名称与API响应中data数组内对象的字段名称完全一致(大小写敏感)
  • 若API字段名称与DTO属性名不一致,可使用@JsonProperty注解指定映射,比如:
@JsonProperty("article_title")
private String title;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 08:12:56