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

如何用Feign Client反序列化Spring Data REST返回的application/json+HAL消息

解决Spring Data REST HAL响应反序列化到自定义模型的问题

我帮你梳理下问题所在和解决步骤,你遇到的空对象问题主要来自HAL响应结构的特殊性、字段映射不匹配,以及缺少必要的序列化支持依赖,下面一步步来解决:

1. 先修复字段映射不匹配的问题

先看你的响应文本里的字段:"admin": true,但你的UserModel里对应的字段是private boolean isAdmin;。Jackson默认的字段映射逻辑对boolean类型的is前缀字段会有歧义,最好显式用@JsonProperty标注来强制映射:

修改UserModel的isAdmin字段:

import com.fasterxml.jackson.annotation.JsonProperty;

public class UserModel extends AbstractNationModelBase implements Serializable {
    // ...其他字段
    @JsonProperty("admin")
    private boolean isAdmin;
    // ...getter、setter和构造方法不变
}

这样就能确保响应里的admin字段正确映射到模型的isAdmin属性上。

2. 添加HAL格式的序列化依赖

Spring Data REST返回的HAL格式需要专门的Jackson模块来解析,如果你是在调用方服务里处理这个响应,需要确保依赖里包含HAL的支持:

Maven 配置(pom.xml)

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

Gradle 配置(build.gradle)

implementation 'org.springframework.boot:spring-boot-starter-data-rest'

这个依赖会自动引入处理HAL格式的Jackson模块,让框架能识别_embedded、_links这类HAL特有的字段。

3. 配置Feign支持HAL格式

Feign默认的消息转换器可能没注册HAL的解析规则,需要自定义Feign配置来添加支持:

创建Feign配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.List;

@Configuration
public class FeignHalConfig {

    @Bean
    public MappingJackson2HttpMessageConverter halMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 明确指定支持HAL_JSON媒体类型
        converter.setSupportedMediaTypes(List.of(MediaTypes.HAL_JSON));
        return converter;
    }
}

然后在你的Feign Client上指定这个配置,同时声明期望接收HAL格式的响应:

import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.Resources;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import feign.FeignClient;

@FeignClient(value="nation-database-service", configuration = FeignHalConfig.class)
public interface UserFeignProxy {
    @RequestMapping(
        method = RequestMethod.GET,
        value="/users",
        produces = MediaTypes.HAL_JSON_VALUE
    )
    Resources<UserModel> GetAllUsersByModel();
}

4. 正确获取反序列化后的对象

调用Feign接口后,你需要通过Resources的getContent()方法拿到实际的用户集合:

// 注入UserFeignProxy
@Autowired
private UserFeignProxy userFeignProxy;

public void fetchUsers() {
    Resources<UserModel> userResources = userFeignProxy.GetAllUsersByModel();
    Iterable<UserModel> users = userResources.getContent();
    // 遍历users就能拿到正确填充的UserModel对象了
    for(UserModel user : users) {
        System.out.println(user.getUsername() + ": " + user.isAdmin());
    }
}

额外选项:轻量化自定义包装类(不依赖Spring HATEOAS)

如果你不想引入Spring HATEOAS的Resources类,也可以自己定义一个匹配HAL结构的包装类:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public class HalUserResponse {
    @JsonProperty("_embedded")
    private EmbeddedUsers embedded;

    // getter和setter
    public EmbeddedUsers getEmbedded() { return embedded; }
    public void setEmbedded(EmbeddedUsers embedded) { this.embedded = embedded; }

    public static class EmbeddedUsers {
        @JsonProperty("users")
        private List<UserModel> users;

        // getter和setter
        public List<UserModel> getUsers() { return users; }
        public void setUsers(List<UserModel> users) { this.users = users; }
    }
}

然后修改Feign接口的返回类型:

@FeignClient(value="nation-database-service")
public interface UserFeignProxy {
    @RequestMapping(method = RequestMethod.GET,value="/users")
    HalUserResponse GetAllUsersByModel();
}

调用时直接获取用户列表:

HalUserResponse response = userFeignProxy.GetAllUsersByModel();
List<UserModel> users = response.getEmbedded().getUsers();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:05:58