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

如何使用RestTemplate调用返回含Page对象的REST API

解决Spring Data Page类型Jackson反序列化问题

问题场景

使用RestTemplate调用返回分页数据的REST API时,遇到Jackson反序列化错误,无法构造org.springframework.data.domain.Page实例。核心错误信息:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.springframework.data.domain.Page` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 12] (through reference chain: net.code.sample.ReportResponse["reports"])

API响应的核心结构:

{
    "reports": {
        "content": [...],
        "pageable": {...},
        "totalElements": 321,
        "totalPages": 4,
        ...
    }
}

当前客户端代码中,ReportResponse类直接使用抽象类Page<Product>作为字段,导致Jackson无法完成实例化。

错误原因

org.springframework.data.domain.Page是抽象类,没有默认构造器或Jackson可识别的创建逻辑,无法直接完成反序列化。必须指定具体的实现类(如PageImpl或自定义子类),并确保Jackson能正确映射JSON字段到类的构造参数。

解决方案

1. 修改ReportResponse类,替换抽象Page为具体实现类

将ReportResponse中的Page<Product>字段改为自定义的CustomPageImpl<Product>,并调整构造器参数类型:

@Data
@Builder
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ReportResponse implements Serializable {

    CustomPageImpl<Product> reportData;

    @JsonCreator
    public ReportResponse(@JsonProperty("reports") CustomPageImpl<Product> reportData) {
        this.reportData = reportData;
    }
}

注:移除不必要的CustomPageImpl继承,ReportResponse作为外层包装类无需继承分页实现类。

2. 修正CustomPageImpl的构造器逻辑

确保CustomPageImpl的@JsonCreator构造器正确使用JSON中的分页参数,而非硬编码值:

public class CustomPageImpl<T> extends PageImpl<T> {

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public CustomPageImpl(@JsonProperty("content") List<T> content,
                          @JsonProperty("number") int number,
                          @JsonProperty("size") int size,
                          @JsonProperty("totalElements") long totalElements,
                          @JsonProperty("pageable") JsonNode pageable,
                          @JsonProperty("last") boolean last,
                          @JsonProperty("totalPages") int totalPages,
                          @JsonProperty("sort") JsonNode sort,
                          @JsonProperty("numberOfElements") int numberOfElements) {
        // 用传入的参数构建正确的Pageable对象
        Pageable pageRequest = PageRequest.of(number, size);
        // 调用父类构造器传入完整分页参数
        super(content, pageRequest, totalElements);
    }

    // 保留其他构造器
    public CustomPageImpl(List<T> content, Pageable pageable, long total) {
        super(content, pageable, total);
    }

    public CustomPageImpl(List<T> content) {
        super(content);
    }

    public CustomPageImpl() {
        super(new ArrayList<>());
    }
}

3. 确保RestTemplate的Jackson配置正确

如果使用Spring Boot,默认RestTemplate已配置Jackson消息转换器;若需自定义,可添加如下配置确保分页类型被正确处理:

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(new ObjectMapper()
            .registerModule(new ParameterNamesModule())
            .registerModule(new Jdk8Module())
            .registerModule(new JavaTimeModule()));
    restTemplate.getMessageConverters().add(0, converter);
    return restTemplate;
}

验证修改

重新调用接口后,Jackson可将reports节点的JSON数据正确反序列化为CustomPageImpl<Product>实例,获取完整的分页元数据和内容列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:33:20