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

如何用Jackson ObjectMapper反序列化含随机整数KEY的JSON?

问题描述

给定JSON响应:

{
  "profile": {
    "userData": {
      "338282892": [
        {
          "userIdentifier": "98shdub777hsjjsuj23",
          "detail": "Test User DEV",
          "type": "customer"
        }
      ]
    }
  }
}

创建UserProfileModel.java后执行反序列化代码:

UserProfileModel model = objectMapper.readValue(body, UserProfileModel.class);

抛出异常:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "338282892"

尝试使用Map<String, List<UserPropertiesModel>>仍有问题,希望反序列化后能直接调用object.getUserIdentifier()或object.getType()方法。


解决方案

方案1:用@JsonAnySetter处理动态键

通过@JsonAnySetter注解捕获动态键值,封装直接获取用户属性的方法:

1. 定义基础属性类

public class UserPropertiesModel {
    private String userIdentifier;
    private String detail;
    private String type;

    // Getters & Setters
    public String getUserIdentifier() { return userIdentifier; }
    public void setUserIdentifier(String userIdentifier) { this.userIdentifier = userIdentifier; }
    public String getDetail() { return detail; }
    public void setDetail(String detail) { this.detail = detail; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
}

2. 处理动态键的UserData类

public class UserData {
    private List<UserPropertiesModel> userProps;

    @JsonAnySetter
    public void captureDynamicKey(String key, List<UserPropertiesModel> value) {
        // 假设动态键对应列表仅含一个元素,直接存储
        if (value != null && !value.isEmpty()) {
            this.userProps = value;
        }
    }

    // 封装直接获取目标属性的方法
    public String getUserIdentifier() {
        return userProps != null && !userProps.isEmpty() ? userProps.get(0).getUserIdentifier() : null;
    }

    public String getType() {
        return userProps != null && !userProps.isEmpty() ? userProps.get(0).getType() : null;
    }

    // 如需获取完整属性对象,可添加此方法
    public UserPropertiesModel getUserProperties() {
        return userProps != null && !userProps.isEmpty() ? userProps.get(0) : null;
    }
}

3. 上层模型类

public class Profile {
    private UserData userData;

    // Getter & Setter
    public UserData getUserData() { return userData; }
    public void setUserData(UserData userData) { this.userData = userData; }
}

public class UserProfileModel {
    private Profile profile;

    // Getter & Setter
    public Profile getProfile() { return profile; }
    public void setProfile(Profile profile) { this.profile = profile; }
}

使用方式

UserProfileModel model = objectMapper.readValue(body, UserProfileModel.class);
String userId = model.getProfile().getUserData().getUserIdentifier();
String userType = model.getProfile().getUserData().getType();

方案2:直接用Map存储并封装快捷方法

将userData定义为Map,在模型类中封装获取属性的快捷方法:

修改Profile类

public class Profile {
    private Map<String, List<UserPropertiesModel>> userData;

    // 封装快捷方法
    public String getUserIdentifier() {
        if (userData == null || userData.isEmpty()) return null;
        List<UserPropertiesModel> propsList = userData.values().iterator().next();
        return propsList.isEmpty() ? null : propsList.get(0).getUserIdentifier();
    }

    public String getType() {
        if (userData == null || userData.isEmpty()) return null;
        List<UserPropertiesModel> propsList = userData.values().iterator().next();
        return propsList.isEmpty() ? null : propsList.get(0).getType();
    }

    // Getter & Setter for userData(如需直接操作Map可保留)
    public Map<String, List<UserPropertiesModel>> getUserData() { return userData; }
    public void setUserData(Map<String, List<UserPropertiesModel>> userData) { this.userData = userData; }
}

使用方式

UserProfileModel model = objectMapper.readValue(body, UserProfileModel.class);
String userId = model.getProfile().getUserIdentifier();
String userType = model.getProfile().getType();

注意事项

  • 若动态键对应的列表可能包含多个元素,需根据业务逻辑调整获取逻辑(比如返回列表或遍历处理)。
  • 无需额外配置FAIL_ON_UNKNOWN_PROPERTIES为false,上述方案已处理动态键的反序列化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:10:28