如何将复杂的JSON反序列化为Java对象

huangapple go评论199阅读模式
英文:

How to deserialize complex JSON to java object

问题

我需要将JSON反序列化为Java类。
我有以下JSON:

  1. {
  2. "data": {
  3. "text": "John"
  4. },
  5. "fields":[
  6. {
  7. "id": "testId",
  8. "name": "fieldName",
  9. "options": {
  10. "color": "#000000",
  11. "required": true
  12. }
  13. },
  14. {
  15. "id": "testId",
  16. "name": "fieldName1",
  17. "options": {
  18. "color": "#000000",
  19. "required": false
  20. }
  21. }
  22. ]
  23. }

我需要将这个JSON(仅限于"fields"部分)反序列化为以下Java类:

  1. public class Field {
  2. public final String id;
  3. public final String name;
  4. public final String color;
  5. public final boolean required;
  6. }

并且我需要获得以下类似的结果:

  1. // 键是字段对象中的id(它可以在多个对象中相同)
  2. 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:

  1. {
  2. &quot;data&quot;: {
  3. &quot;text&quot;: &quot;John&quot;
  4. },
  5. &quot;fields&quot;:[
  6. {
  7. &quot;id&quot;: &quot;testId&quot;,
  8. &quot;name&quot;: &quot;fieldName&quot;,
  9. &quot;options&quot;: {
  10. &quot;color&quot;: &quot;#000000&quot;,
  11. &quot;required&quot;: true
  12. }
  13. },
  14. {
  15. &quot;id&quot;: &quot;testId&quot;,
  16. &quot;name&quot;: &quot;fieldName1&quot;,
  17. &quot;options&quot;: {
  18. &quot;color&quot;: &quot;#000000&quot;,
  19. &quot;required&quot;: false
  20. }
  21. }
  22. ]
  23. }

and I need to deserialize this JSON (only "fields" section) to java class like the following:

  1. public class Field {
  2. public final String id;
  3. public final String name;
  4. public final String color;
  5. public final boolean required;
  6. }

and I need to get something like the following:

  1. // The key is the id from field object (it can be the same in the multiple objects.)
  2. Map&lt;String, List&lt;Field&gt;&gt; fields = objectMapper.readValue(json, Map&lt;String, List&lt;Field&gt;&gt;);

How can I do it using Jackson?

答案1

得分: 1

> 只要jackson不支持@JsonWrapped,您就必须使用以下解决方法。

首先,您需要创建一个包含fields的自定义类:

  1. public class Fields {
  2. public List<Field> fields;
  3. }

根据您的ObjectMapper配置,您需要向Fields类添加@JsonIgnoreProperties(ignoreUnknown = true),以忽略任何其他属性。

接下来,您必须定义仅用于临时使用的嵌套Options类:

  1. public class Options {
  2. public String color;
  3. public boolean required;
  4. }

最后,将此构造函数添加到您的Field类中:

  1. @JsonCreator
  2. public Field(@JsonProperty("id") String id, @JsonProperty("name") String name, @JsonProperty("options") Options options){
  3. this.id = id;
  4. this.name = name;
  5. this.color = options.color;
  6. this.required = options.required;
  7. }

@JsonCreator注解告诉jackson需要使用此构造函数进行反序列化。此外,@JsonProperty注解是必需的,因为构造函数和方法的参数不会保留在字节码中。

然后,您可以像这样反序列化您的json数据:

  1. 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:

  1. public class Fields {
  2. public List&lt;Field&gt; fields;
  3. }

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:

  1. public class Options {
  2. public String color;
  3. public boolean required;
  4. }

And at last add this constructor to your Field class:

  1. @JsonCreator
  2. public Field(@JsonProperty(&quot;id&quot;) String id, @JsonProperty(&quot;name&quot;) String name, @JsonProperty(&quot;options&quot;) Options options){
  3. this.id = id;
  4. this.name = name;
  5. this.color = options.color;
  6. this.required = options.required;
  7. }

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:

  1. List&lt;Field&gt; fields = objectMapper.readValue(json, Fields.class).fields;

huangapple
  • 本文由 发表于 2020年7月22日 16:23:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63029927.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定