Java 使用jackson转换带有重复密钥的JSON

Java 使用jackson转换带有重复密钥的JSON,java,json,jackson,jackson-databind,Java,Json,Jackson,Jackson Databind,我正在将json转换为java对象,但我没有得到我想要的。 我在json中复制了密钥“friend” 我的json: { "id" : "5ee2e2f780bc8e7511a65de9", "friends": [{ "friend": { "id": 1, "name": "Priscilla Lynch" }, "friend": { "id": 2,

我正在将json转换为java对象,但我没有得到我想要的。 我在json中复制了密钥“friend”

我的json:

{
    "id" : "5ee2e2f780bc8e7511a65de9",
    "friends": [{
        "friend": {
            "id": 1,
            "name": "Priscilla Lynch"
        },
        "friend": {
            "id": 2,
            "name": "William Lawrence"
        }
    }]
}
从ObjectMapper使用readValue只需要最后一个“朋友”,但我需要这两个。 我知道JSONObject使用Map进行转换,所以它使用最后一个

结果: 联系人(id=5ee2e2f780bc8e7511a65de9,friends=[{friend={id=2,name=William Lawrence}}}])

联系Pojo:

@Getter
@Setter
@ToString
public class Contacts {

    String id;
    List<Object> friends;
}
@Getter
@塞特
@托斯特林
公共类联系人{
字符串id;
列出朋友;
}
我要一份所有朋友的名单。由于提供json的服务不在我手中,我需要找到一种解决方法。 我尝试使用apache.commons中的MultiMap,但没有成功。 我对此一窍不通。

也创建“Friend”的POJO类,然后像这样编辑“Contacts”类

public class Contacts {
   String id;
   List<Friend> friends;
}
公共类联系人{
字符串id;
列出朋友;
}

然后,当您有一个带有重复字段的
JSON对象时,您应该可以使用
com.fasterxml.jackson.annotation.JsonAnySetter
annotation来获得好友项列表。结果将是一个
列表
,因此,您可以使用
flatMap
方法创建
List
。请参见以下示例:

import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class DuplicatedFieldsInJsonObjectApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = JsonMapper.builder().build();
        Contacts contacts = mapper.readValue(jsonFile, Contacts.class);
        System.out.println(contacts.getUnwrappedFriends());
    }
}

@Getter
@Setter
@ToString
class Contacts {

    String id;
    List<Friends> friends;

    public List<Friend> getUnwrappedFriends() {
        return friends.stream().flatMap(f -> f.getFriends().stream()).collect(Collectors.toList());
    }
}

class Friends {

    private List<Friend> friends = new ArrayList<>();

    @JsonAnySetter
    public void setAny(String property, Friend friend) {
        friends.add(friend);
    }

    public List<Friend> getFriends() {
        return friends;
    }
}

@Getter
@Setter
@ToString
class Friend {
    int id;
    String name;
}

你需要
Friend
作为对象吗?因为你可以从
JsonNode
中提取它们,而无需对它们进行反序列化。是的,我需要一个朋友列表。你的json有点奇怪。在同一节点中有两个同名的字段
friend
。这使得杰克逊只能选择其中一个(最后一个)。因此,即使您使用JsonNode处理它,第一个
friend
也会丢失。您可以执行这个
JsonNode JsonNode=mapper.readTree(json);System.out.println(jsonNode.get(“friends”).get(0.toString())
它打印数组的第一个元素
friends
。它只打印了一个,而不是两个。在我看来,json是“错误的”。您的
朋友
是这样的
[{{},{}}]
@KunLun,
JSON
负载是有效的。对象结构表示为围绕零个或多个名称/值对的一对花括号标记。名称是一个字符串。每个名称后面都有一个冒号标记,将名称与值分开。单个逗号标记将值与以下名称分隔开。JSON语法不对用作名称的字符串施加任何限制,不要求名称字符串是唯一的,也不为名称/值对的顺序分配任何意义。您错过了
friends
是一个包含单个对象的数组:
friends[{{{friend},{friend}}]
。我尝试了这种方法,但我发现我的
@JsonAnySetter
注释方法在我
Sys.out
时没有得到重复的条目。我的意思是,当我在
@jsonanyster
带注释的方法中打印
时,即使是重复的
和最后一个值,我也只能看到一个条目。这就好像
Jackson
在使用此方法之前已经忽略了重复的条目。我已经把我的问题贴在这里了。一个机会,请让我知道我该怎么做。
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class DuplicatedFieldsInJsonObjectApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = JsonMapper.builder().build();
        Contacts contacts = mapper.readValue(jsonFile, Contacts.class);
        System.out.println(contacts.getUnwrappedFriends());
    }
}

@Getter
@Setter
@ToString
class Contacts {

    String id;
    List<Friends> friends;

    public List<Friend> getUnwrappedFriends() {
        return friends.stream().flatMap(f -> f.getFriends().stream()).collect(Collectors.toList());
    }
}

class Friends {

    private List<Friend> friends = new ArrayList<>();

    @JsonAnySetter
    public void setAny(String property, Friend friend) {
        friends.add(friend);
    }

    public List<Friend> getFriends() {
        return friends;
    }
}

@Getter
@Setter
@ToString
class Friend {
    int id;
    String name;
}
[Friend(id=1, name=Priscilla Lynch), Friend(id=2, name=William Lawrence)]