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

RestTemplate调用返回PagedResources<Resource<EmployeeDto>>接口无内容问题

解决RestTemplate无法反序列化PagedResources<Resource>的问题

看起来你遇到的问题是RestTemplate默认配置没法处理Spring HATEOAS返回的HAL格式分页数据——毕竟Postman能拿到完整响应,说明接口本身没问题,问题出在客户端的反序列化环节。

核心原因

Spring HATEOAS返回的PagedResources对应的JSON是HAL格式,包含_embedded、_links和page这些特殊字段,而RestTemplate默认的MappingJackson2HttpMessageConverter没有配置对应的HAL模块,没法把这些特殊字段映射到PagedResources和Resource对象里,导致反序列化后拿不到有效内容。

解决方案步骤

1. 确保依赖到位

首先检查项目依赖,确保引入了Spring HATEOAS相关包(以Maven为例):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>

这个依赖会自动引入HAL序列化/反序列化的核心模块。

2. 正确配置RestTemplate

不要直接new RestTemplate(),而是通过RestTemplateBuilder构建,它会自动注册处理HAL格式的HalMessageConverter:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

如果是在非Spring容器环境下手动创建,也可以手动添加转换器:

ObjectMapper objectMapper = new ObjectMapper()
        .registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter halConverter = new MappingJackson2HttpMessageConverter(objectMapper);
halConverter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));

RestTemplate template = new RestTemplate();
// 把HAL转换器放到最前面,确保优先处理HAL格式响应
template.getMessageConverters().add(0, halConverter);

3. 正确使用ParameterizedTypeReference

调用接口时,用ParameterizedTypeReference明确指定泛型类型(和你之前用的TypeReferences.PagedResourcesType本质一致,确保类型匹配即可):

String uri = "http://localhost:8080/employee-api/employees/160166/employees?page=0&size=25";
// 使用上面配置好的RestTemplate实例
RestTemplate template = restTemplate;

ResponseEntity<PagedResources<Resource<EmployeeDto>>> response = template.exchange(
        uri,
        HttpMethod.GET,
        null,
        new ParameterizedTypeReference<PagedResources<Resource<EmployeeDto>>>() {}
);

PagedResources<Resource<EmployeeDto>> pagedResources = response.getBody();
// 现在可以正常读取内容了
pagedResources.getContent().forEach(resource -> {
    EmployeeDto dto = resource.getContent();
    System.out.println("员工编号: " + dto.getEmployeeNumber() + ", 状态: " + dto.getStatus());
});

4. 检查EmployeeDto的序列化配置

确保EmployeeDto类有无参构造函数,并且字段名称和JSON响应中的键匹配(如果有名称不一致的情况,可以用@JsonProperty注解调整):

public class EmployeeDto {
    private String employeeNumber;
    private String status;

    // 必须保留无参构造函数,否则Jackson无法反序列化
    public EmployeeDto() {}

    // Getter & Setter
    public String getEmployeeNumber() {
        return employeeNumber;
    }

    public void setEmployeeNumber(String employeeNumber) {
        this.employeeNumber = employeeNumber;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}

为什么用String能正常获取?

因为指定String.class作为响应类型时,RestTemplate不会执行任何反序列化操作,直接返回HTTP响应的原始JSON字符串,所以能看到完整内容,但无法直接拿到结构化的PagedResources对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:49:33