英文:
How to deserialize complex JSON to java object
问题
我需要将JSON反序列化为Java类。
我有以下JSON:
{
  "data": {
    "text": "John" 
  },
  "fields":[
    {
      "id": "testId",
      "name": "fieldName",
      "options": {
        "color": "#000000",
        "required": true
      }
    },
    {
      "id": "testId",
      "name": "fieldName1",
      "options": {
        "color": "#000000",
        "required": false
      }
    }
  ]
}
我需要将这个JSON(仅限于"fields"部分)反序列化为以下Java类:
public class Field {
    public final String id;
    public final String name;
    public final String color;
    public final boolean required;
}
并且我需要获得以下类似的结果:
// 键是字段对象中的id(它可以在多个对象中相同)
Map<String, List<Field>> fields = objectMapper.readValue(json, new TypeReference<Map<String, List<Field>>>() {});
如何使用Jackson做到这一点?
英文:
I need to deserialize JSON to java class.<br/>
I have JSON like the following:
{
  "data": {
    "text": "John" 
  },
  "fields":[
    {
      "id": "testId",
      "name": "fieldName",
      "options": {
        "color": "#000000",
        "required": true
      }
    },
    {
      "id": "testId",
      "name": "fieldName1",
      "options": {
        "color": "#000000",
        "required": false
      }
    }
  ]
}
and I need to deserialize this JSON (only "fields" section) to java class like the following:
public class Field {
    public final String id;
    public final String name;
    public final String color;
    public final boolean required;
}
and I need to get something like the following:
// The key is the id from field object (it can be the same in the multiple objects.)
Map<String, List<Field>> fields = objectMapper.readValue(json, Map<String, List<Field>>);
How can I do it using Jackson?
答案1
得分: 1
> 只要jackson不支持@JsonWrapped,您就必须使用以下解决方法。
首先,您需要创建一个包含fields的自定义类:
public class Fields {
    public List<Field> fields;
}
根据您的ObjectMapper配置,您需要向Fields类添加@JsonIgnoreProperties(ignoreUnknown = true),以忽略任何其他属性。
接下来,您必须定义仅用于临时使用的嵌套Options类:
public class Options {
    public String color;
    public boolean required;
}
最后,将此构造函数添加到您的Field类中:
@JsonCreator
public Field(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("options") Options options){
    this.id = id;
    this.name = name;
    this.color = options.color;
    this.required = options.required;
}
@JsonCreator注解告诉jackson需要使用此构造函数进行反序列化。此外,@JsonProperty注解是必需的,因为构造函数和方法的参数不会保留在字节码中。
然后,您可以像这样反序列化您的json数据:
List<Field> fields = objectMapper.readValue(json, Fields.class).fields;
英文:
> As long as jackson doesn't support @JsonWrapped, you have to use the following work around.
First you need to create a custom class which contains the fields:
public class Fields {
    public List<Field> fields;
}
Depending on your ObjectMapper configuration you have to add @JsonIgnoreProperties(ignoreUnknown = true) to the Fields class, to ignore any other properties.
Next is that you have to define the nested Options class which is solely used temporarily:
public class Options {
    public String color;
    public boolean required;
}
And at last add this constructor to your Field class:
@JsonCreator
public Field(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("options") Options options){
    this.id = id;
    this.name = name;
    this.color = options.color;
    this.required = options.required;
}
The @JsonCreator annotation indicates to jackson that this constructor needs to be used for the deserialization. Also the @JsonProperty annotations are required as arguments to constructors and methods are not preserved in the bytecode
Then you can deserialize your json just like this:
List<Field> fields = objectMapper.readValue(json, Fields.class).fields;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论