使用Jackson将Adobe Campaign API响应转为List<POJO>遇阻求助
获取响应数据的代码
String json = EntityUtils.toString(response.getEntity());
返回的JSON结构(已精简)
{ "content": [ { "PKey": "@9v59tLj9c.....", "age": 36, "birthDate": "1986-04-30", "blackList": false, ... }, ... ] }
已配置的Jackson ObjectMapper
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true); objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
尝试过的解析方式及报错
直接解析为Profile类
Profile profile = objectMapper.readValue(json, Profile.class);报错:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "content" (class com.example.adobecampaignprototype.Profile), not marked as ignorable (0 known properties: ])使用ObjectReader指定根节点
ObjectReader objectReader = objectMapper.readerFor(Profile.class).withRootName("content"); Profile profile = objectReader.readValue(json);报错:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of typecom.example.adobecampaignprototype.Profilefrom Array value (tokenJsonToken.START_ARRAY)尝试转换为ArrayNode
ArrayNode arrayNode = (ArrayNode) objectMapper.readTree(json).get("content");报错:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "content" (class com.example.adobecampaignprototype.Profile), not marked as ignorable (0 known properties: ])逐节点读取单个属性
JsonNode jsonNodeRoot = objectMapper.readTree(json); JsonNode jsonNodeNested = jsonNodeRoot.get("content"); JsonNode jsonNodeActual = jsonNodeNested.get(0); // 获取索引0的Profile JsonNode jsonNodeActualValue = jsonNodeActual.get("PKey"); // 读取单个属性(此方式仅能读取单个属性,无法直接解析为POJO)
可行的解决方法
1. 创建包装类匹配JSON结构
创建一个包含List<Profile>的包装类,直接解析为该类后取出列表:
// 包装类定义 public class ContentWrapper { private List<Profile> content; // 必须提供getter和setter,或使用@Data注解(Lombok) public List<Profile> getContent() { return content; } public void setContent(List<Profile> content) { this.content = content; } } // 解析代码 ContentWrapper wrapper = objectMapper.readValue(json, ContentWrapper.class); List<Profile> profiles = wrapper.getContent(); // 取单个Profile Profile firstProfile = profiles.get(0);
2. 解析数组节点并转换为POJO列表
先读取JSON树获取content数组节点,再转换为List<Profile>:
JsonNode rootNode = objectMapper.readTree(json); ArrayNode contentNode = (ArrayNode) rootNode.get("content"); List<Profile> profiles = objectMapper.convertValue(contentNode, new TypeReference<List<Profile>>() {});
3. 使用ObjectReader直接解析数组类型
配置ObjectReader读取List<Profile>并指定根节点为content:
ObjectReader reader = objectMapper.readerFor(new TypeReference<List<Profile>>() {}).withRootName("content"); List<Profile> profiles = reader.readValue(json);
关键注意事项
确保Profile类的字段与JSON键名匹配,若Java字段名与JSON不一致(如JSON的PKey对应Java的pKey),需添加@JsonProperty注解:
public class Profile { @JsonProperty("PKey") private String pKey; private Integer age; @JsonProperty("birthDate") private LocalDate birthDate; @JsonProperty("blackList") private Boolean blackList; // 其他字段及getter/setter }
内容的提问来源于stack exchange,提问作者scadh

