将JSON对象数组映射到java.util。地图,反之亦然

时间:2021-08-09 19:38:23

The question is how to map an array of JSON objects to a java.util.Map where each key would be some specified property of an object and the value is the object itself.

问题是如何将JSON对象数组映射到java.util。映射每个键将是一个对象的指定属性,而值是对象本身。

JSON:

JSON:

{"items": [{"field1": 1, "field2": "Hello"}, {"field1": 2, "field2":"World"}]}

Java POJO:

Java POJO:

public class Storage {
    private Map<Integer, Item> items;
}

public class Item {
    private Integer field1;
    private String field2;
}

So is there a some way to specify to ObjectMapper that it should use field1 property of each JSON object as key when deserializing array of items to the Map?

那么,是否有一种方法可以指定ObjectMapper,它应该将每个JSON对象的field1属性作为键,将数组中的项反序列化到映射中?

3 个解决方案

#1


7  

How to deserialize a JSON string

如何反序列化JSON字符串?

You can use Jackson to deserialize a JSON string:

您可以使用Jackson来反序列化JSON字符串:

For example if you have class Foo

例如,如果你有Foo类

public class Foo {

   private Bar[] items;

   // Constructor / Getters & Setters

} 

And that class has an array of class Bar

这个类有一个类Bar的数组

 public class Bar {

     private int field1;
     private String field2;


     // Constructor / Getters & Setters

 }

Where the field names match those in your JSON string then you can do the following to convert it:

如果字段名与JSON字符串中的字段名匹配,那么您可以执行以下操作来转换它:

String jsonString = "{\"items\": [{\"field1\": 1, \"field2\": \"Hello\"}, {\"field1\": 2, \"field2\":\"World\"}]}";

ObjectMapper mapper = new ObjectMapper();

Foo foo = mapper.readValue(jsonString, Foo.class);

If you are using Maven, the following dependency would be required in your pom.xml:

如果您正在使用Maven,则在您的pom.xml中需要以下依赖项:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>

Approaches to solve your problem:

解决问题的方法:

Option 1 - Custom Deserializer

选项1 -自定义反序列化器

Write a custom JsonDeserializer to deserialize your JSON string into a Storage object with a field items of type Map<String,Item>

编写一个自定义的JsonDeserializer,以便将JSON字符串反序列化为一个存储对象,其中包含Map< string,Item>类型的字段项

 public class CustomDeserializer extends JsonDeserializer<Storage> {

    @Override
    public Storage deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {

        Map<Integer, Item> map = new HashMap<>();

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode rootNode = oc.readTree(jsonParser);
        JsonNode items = rootNode.get("items");

        for (int i = 0; i < items.size(); i++) {

            JsonNode childNode = items.get(i);

            Item item = new Item(childNode.get("field1").asInt(), childNode.get("field2").asText());

            map.put(item.getField1(), item);
        }

        return new Storage(map);
    }
}

You would then annotate your Storage class with the following:

然后,您将在存储类中注释如下:

@JsonDeserialize(using = CustomDeserializer.class)

Your Storage class would look something like;

您的存储类看起来是这样的;

@JsonDeserialize(using = CustomDeserializer.class)
public class Storage {

   private Map<Integer, Item> items;

   public Storage(Map<Integer, Item> map) {
    this.items = map;
   }

   ...

}

Option 2 - Create Map post deserialization

选项2 -创建映射后反序列化

Deserialize the JSON string into a Storage object with an array of Item as described at the beginning and then construct your Map<Integer, Item> after.

将JSON字符串反序列化为存储对象,并使用开头描述的项数组,然后构造映射 ,>

Hope this helps.

希望这个有帮助。

#2


1  

You can create your own custom Serializers/Deserializers to achieve this. Jackson provides a neat way of doing this. Just annotate the Storage class with @JsonDeserialize(using = YourDeserializer.class) and have the logic to convert the json in YourDeserializer.

您可以创建自己的自定义序列化器/反序列化器来实现这一点。Jackson提供了一种简洁的方法。只需使用@JsonDeserialize(使用= yourdeserizer .class)注释存储类,并具有在YourDeserializer中转换json的逻辑。

#3


0  

The array of JSON objects is an array of Items, right? So why not simply deserialize the array into a Java array of Items and then build the Map from there?

JSON对象的数组是项目的数组,对吧?那么,为什么不简单地将数组反序列化为项目的Java数组,然后从那里构建映射呢?

#1


7  

How to deserialize a JSON string

如何反序列化JSON字符串?

You can use Jackson to deserialize a JSON string:

您可以使用Jackson来反序列化JSON字符串:

For example if you have class Foo

例如,如果你有Foo类

public class Foo {

   private Bar[] items;

   // Constructor / Getters & Setters

} 

And that class has an array of class Bar

这个类有一个类Bar的数组

 public class Bar {

     private int field1;
     private String field2;


     // Constructor / Getters & Setters

 }

Where the field names match those in your JSON string then you can do the following to convert it:

如果字段名与JSON字符串中的字段名匹配,那么您可以执行以下操作来转换它:

String jsonString = "{\"items\": [{\"field1\": 1, \"field2\": \"Hello\"}, {\"field1\": 2, \"field2\":\"World\"}]}";

ObjectMapper mapper = new ObjectMapper();

Foo foo = mapper.readValue(jsonString, Foo.class);

If you are using Maven, the following dependency would be required in your pom.xml:

如果您正在使用Maven,则在您的pom.xml中需要以下依赖项:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>

Approaches to solve your problem:

解决问题的方法:

Option 1 - Custom Deserializer

选项1 -自定义反序列化器

Write a custom JsonDeserializer to deserialize your JSON string into a Storage object with a field items of type Map<String,Item>

编写一个自定义的JsonDeserializer,以便将JSON字符串反序列化为一个存储对象,其中包含Map< string,Item>类型的字段项

 public class CustomDeserializer extends JsonDeserializer<Storage> {

    @Override
    public Storage deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException {

        Map<Integer, Item> map = new HashMap<>();

        ObjectCodec oc = jsonParser.getCodec();
        JsonNode rootNode = oc.readTree(jsonParser);
        JsonNode items = rootNode.get("items");

        for (int i = 0; i < items.size(); i++) {

            JsonNode childNode = items.get(i);

            Item item = new Item(childNode.get("field1").asInt(), childNode.get("field2").asText());

            map.put(item.getField1(), item);
        }

        return new Storage(map);
    }
}

You would then annotate your Storage class with the following:

然后,您将在存储类中注释如下:

@JsonDeserialize(using = CustomDeserializer.class)

Your Storage class would look something like;

您的存储类看起来是这样的;

@JsonDeserialize(using = CustomDeserializer.class)
public class Storage {

   private Map<Integer, Item> items;

   public Storage(Map<Integer, Item> map) {
    this.items = map;
   }

   ...

}

Option 2 - Create Map post deserialization

选项2 -创建映射后反序列化

Deserialize the JSON string into a Storage object with an array of Item as described at the beginning and then construct your Map<Integer, Item> after.

将JSON字符串反序列化为存储对象,并使用开头描述的项数组,然后构造映射 ,>

Hope this helps.

希望这个有帮助。

#2


1  

You can create your own custom Serializers/Deserializers to achieve this. Jackson provides a neat way of doing this. Just annotate the Storage class with @JsonDeserialize(using = YourDeserializer.class) and have the logic to convert the json in YourDeserializer.

您可以创建自己的自定义序列化器/反序列化器来实现这一点。Jackson提供了一种简洁的方法。只需使用@JsonDeserialize(使用= yourdeserizer .class)注释存储类,并具有在YourDeserializer中转换json的逻辑。

#3


0  

The array of JSON objects is an array of Items, right? So why not simply deserialize the array into a Java array of Items and then build the Map from there?

JSON对象的数组是项目的数组,对吧?那么,为什么不简单地将数组反序列化为项目的Java数组,然后从那里构建映射呢?