Java 将 JSON 转换为具有特定字段作为键和值的映射的代码

Java code to Convert JSON into a Map with specific fields as Key and values

我有一个JSON如下

[
    {
        "a": "John",
        "id": "6",
        "c": "val1"
    },
    {
        "a": "Jack",
        "id": "6",
        "c": "val2"            
    },
    {
        "a": "Joe",
        "id": "6",
        "c": "val3"
    }
]

我需要将其转换为 Map 以便字段 'a' 的值成为键,字段 'c' 的值成为 Map 中的值.

换句话说,我的地图应该如下所示:

John:val1
Jack:val2
Joe:val3

完成此操作的最短路径是什么?

另外,我想知道是否可以在这里利用 RestAssured GPath

像这样 -

new JsonPath(jsonPayload).getString("findAll { json -> json.id == '6' }.a");

你在找 JsonSlurper 吗?

import groovy.json.JsonSlurper

String json = '''
[
    {
        "a": "John",
        "id": "6",
        "c": "val1"
    },
    {
        "a": "Jack",
        "id": "6",
        "c": "val2"            
    },
    {
        "a": "Joe",
        "id": "6",
        "c": "val3"
    }
    
]
'''

def root = new JsonSlurper().parseText(json)
def result = root.findAll{it.id == '6'}.collectEntries{[it.a, it.c]}
print(result)

您可以先将其转换为 YourObject 的列表,然后他们按照您想要的规则将其转换为地图 (key = a, value = c)

创建代表 json 对象的 class:

 class YourObject
 {
     String a;
     String id;
     String c;

     // contructors
     // getters and setters    
 }

使用 Gson:

将您的 JSON 反序列化到其中
String json = "<PUT YOUR JSON HERE>";

List<YourObject> list = new GsonBuilder().create().fromJson(json, new TypeToken<List<YourObject>>(){}.getType());

然后将其转换为地图:

Map<String, String> map = list.stream().collect(Collectors.toMap(YourObject::getA, YourObject::getC));

如果您想按特定 ID(例如 ID=6)进行过滤,您可以这样做:

Map<String, String> map = list.stream()
            .filter(yo -> yo.getId().equals("6"))
            .collect(Collectors.toMap(YourObject::getA, YourObject::getC));

你可以使用jsonpath库来制作它。将其添加到您的 pom.xml:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>

然后尝试下面的代码

// read the a, c of json string by the JsonPath libraby
List<String> aList = JsonPath.read(json, "$.[*].a");
List<String> cList = JsonPath.read(json, "$.[*].c");

// combine two list to a map
Iterator<String> i1 = aList.iterator();
Iterator<String> i2 = cList.iterator();
Map<String, String> map = new HashMap<>();
while (i1.hasNext() && i2.hasNext()) {
    map.put(i1.next(), i2.next());
}

// print it 
map.forEach((k,v) -> System.out.println(k + ":" + v));

查看更多关于 jsonpath

您可以使用 jackson 例如:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.2.2</version>
</dependency>

我会为生成的 Map 和自定义反序列化器创建一个包装器。

@JsonDeserialize(using = MapWrapperDeserializer.class)
public class MapWrapper {

  private final Map<String, String> map;

  public MapWrapper(Map<String, String> map) {
    this.map = map;
  }

  public Map<String, String> getMap() {
    return this.map;
  }
}

解串器:

public class MapWrapperDeserializer extends StdDeserializer<MapWrapper> {

  public MapWrapperDeserializer() {
    super(MapWrapper.class);
  }

  @Override
  public MapWrapper deserialize(JsonParser parser, DeserializationContext context) throws IOException {
    JsonNode array = parser.getCodec().readTree(parser);
    int size = array.size();
    Map<String, String> map = new LinkedHashMap<>(size);
    for (JsonNode element : array) {
      String key = element.get("a").asText();
      String value = element.get("c").asText();
      map.put(key, value);
    }
    return new MapWrapper(map);
  }
}

一个简单的测试:

public class Temp {

  public static void main(String[] args) throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    InputStream dataStream = getInputStreamOrJsonString();
    MapWrapper wrapper = mapper.readValue(dataStream, MapWrapper.class);
    System.out.println(wrapper.getMap());
  }
}