You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring中JSON键动态变化时响应转Java对象的实现方案

嘿,这个问题我之前处理过,其实对付这种动态键名的JSON结构,Jackson+RestTemplate有几种很直接的解决办法,我给你梳理下:

方法一:直接用Map<String, Employee>接收

这是最简洁的方案,因为你的JSON结构本质就是「字符串键(员工名)对应员工对象」,完全匹配Java Map的结构。

首先确保你的Employee类定义正确(字段和JSON对应,要有getter/setter或者用Lombok简化):

public class Employee {
    private int employeeId;
    private int active;
    private int hours;

    // 无参构造、全参构造
    // getter和setter方法,或者用@Data注解(Lombok)自动生成
}

然后用RestTemplate调用API时,通过TypeReference指定泛型类型(直接传Map.class的话Jackson无法识别泛型参数):

RestTemplate restTemplate = new RestTemplate();
String apiUrl = "你的外部API地址";

// 用TypeReference告诉Jackson要解析成<String, Employee>的Map
Map<String, Employee> employeeMap = restTemplate.exchange(
    apiUrl,
    HttpMethod.GET,
    null,
    new ParameterizedTypeReference<Map<String, Employee>>() {}
).getBody();

拿到Map之后,你就可以通过员工名直接获取对应的信息,比如employeeMap.get("Jack")就能拿到Jack的Employee对象。

方法二:自定义响应类+@JsonAnySetter

如果想把动态键的逻辑封装在一个专门的响应类里,可以用Jackson的@JsonAnySetter注解来收集所有动态键值对:

public class EmployeeResponse {
    // 用Map存储所有员工,键是名字,值是Employee对象
    private Map<String, Employee> employees = new HashMap<>();

    // 这个注解会让Jackson把所有未匹配到固定字段的键值对都调用这个方法
    @JsonAnySetter
    public void addEmployee(String name, Employee employee) {
        employees.put(name, employee);
    }

    // getter方法,方便外部获取employees Map
    public Map<String, Employee> getEmployees() {
        return employees;
    }
}

然后调用API时直接返回这个类:

EmployeeResponse response = restTemplate.getForObject(apiUrl, EmployeeResponse.class);
Map<String, Employee> employeeMap = response.getEmployees();

额外:转换成带名字的员工列表

如果后续业务需要把Map转换成包含员工名字的列表,可以做个简单的流式转换:

先定义一个包含名字的员工类:

public class EmployeeWithName {
    private String name;
    private Employee employee;

    public EmployeeWithName(String name, Employee employee) {
        this.name = name;
        this.employee = employee;
    }

    // getter和setter
}

然后转换:

List<EmployeeWithName> employeeList = employeeMap.entrySet().stream()
    .map(entry -> new EmployeeWithName(entry.getKey(), entry.getValue()))
    .collect(Collectors.toList());

这样就能得到每个员工都包含名字的列表,方便后续业务处理。

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

火山引擎 最新活动