反序列化具有嵌套属性的JSON对象。

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

Deserialize JSON Object with nested attributes

问题

我正在尝试反序列化一个具有以下属性的 JSON 对象

其中第一个键名是未知的而内部映射始终包含两个名为 "key1""key2" 的属性

```json
{
   "operation_rand":
   {
      "key1": 1005, 
      "key2": 5
   }
}

我有以下代码:

Operation.java

public class Operation {
    private Map<String, Map<String, Integer>> operationDetails = new HashMap<>();

    @JsonAnyGetter
    public Map<String, Map<String, Integer>> getOperation() {
        return operationDetails;
    }
} 

Main

ObjectMapper mapper = new ObjectMapper();

Operation op = mapper.readValue(jsonData, Operation.class);
Map<String, Map<String, Integer>> oDetails = op.getOperation();

然而我得到了错误:
在第 1 行,第 25 列无法将 java.lang.String 的实例反序列化为 START_OBJECT 标记,这是内部映射开始的地方。

有关如何映射内部映射的任何想法吗?
如果映射只有一层深,我可以获取正确的值。

{
   "operation_rand": 100
}

并将上述映射调整为 Map<String, Integer>


<details>
<summary>英文:</summary>

I am trying to deserialize a json object with the attributes

Where the first key name is unknown, while the inner map always contains two attributes named &quot;key1&quot; and &quot;key2&quot;.

{
"operation_rand":
{
"key1": 1005,
"key2": 5
}
}


I have the code :

Operation.java

public class Operation {
private Map<String, Map<String, Integer>> operationDetails = new HashMap<>();

@JsonAnyGetter
public Map&lt;String, Map&lt;String, Integer&gt;&gt; getOperation() {
    return operationDetails;
}

}


Main

ObjectMapper mapper = new ObjectMapper();

Operation op = mapper.readValue(jsonData, Operation.class);
Map<String, Map<String, Integer>> oDetails = address.getOperation();


However I get the error:
`Can not deserialize instance of java.lang.String out of START_OBJECT token` at line: 1, column: 25, which is where the inner map starts.  

Any ideas on how I can map the inner map?
I can grab the correct value if the map was only one layer deep.

{
"operation_rand": 100
}

And adjusting the above maps to just `Map&lt;String, Integer&gt;`






</details>


# 答案1
**得分**: 2

你需要一个用于预期的 JSON 的对象表示,以及一个 Gson 依赖。

对象的类如下:

```java
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName("operation_rand")
public class OperationRand {
    @JsonProperty("key1")
    private int key1;
    @JsonProperty("key2")
    private int key2;

    public int getKey1() {
        return key1;
    }

    public void setKey1(int key1) {
        this.key1 = key1;
    }

    public int getKey2() {
        return key2;
    }

    public void setKey2(int key2) {
        this.key2 = key2;
    }

    public OperationRand(int key1, int key2) {
        this.key1 = key1;
        this.key2 = key2;
    }

    @Override
    public String toString() {
        return "OperationRand{" +
                "key1=" + key1 +
                ", key2=" + key2 +
                '}';
    }
}

Gson(来自 Google)的依赖如下:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

然后,可以如下使用:

String json = "{'operation_rand': {'key1': 1005, 'key2': 5}}";
Gson gson = new Gson();
OperationRand res = gson.fromJson(json, OperationRand.class);
System.out.println(res);

对于更改的 operation_rand,你可以使用对象来表示不变的字段:

import lombok.*;

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Key {
    int key1;
    int key2;
}

在主要部分中:

Gson gson = new Gson();
Map<String, Key> rest = gson.fromJson(json, HashMap.class);
System.out.println(rest);
英文:

You need an Object Representation for the expected JSON a Gson dependency

Class for the Object


    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonRootName;

    @JsonRootName(&quot;operation_rand&quot;)
    public class OperationRand{
    @JsonProperty(&quot;key1&quot;)
    private int key1;
    @JsonProperty(&quot;key2&quot;)
    private int key2;

    public int getKey1() {
        return key1;
    }

    public void setKey1(int key1) {
        this.key1 = key1;
    }

    public int getKey2() {
        return key2;
    }

    public void setKey2(int key2) {
        this.key2 = key2;
    }

    public OperationRand(int key1, int key2) {
        this.key1 = key1;
        this.key2 = key2;
    }

    @Override
    public String toString() {
        return &quot;OperationRand{&quot; +
                &quot;key1=&quot; + key1 +
                &quot;, key2=&quot; + key2 +
                &#39;}&#39;;
    }
    }

Gson From Google

    &lt;dependency&gt;

		&lt;groupId&gt;com.google.code.gson&lt;/groupId&gt;

		&lt;artifactId&gt;gson&lt;/artifactId&gt;

    &lt;/dependency&gt;

Then,

    String json =&quot;{\n&quot; +
				&quot;   \&quot;operation_rand\&quot;:\n&quot; +
				&quot;   {\n&quot; +
				&quot;      \&quot;key1\&quot;: 1005, \n&quot; +
				&quot;      \&quot;key2\&quot;: 5\n&quot; +
				&quot;   }\n&quot; +
				&quot;}&quot;;
    Gson gson = new Gson();
    OperationRand res = gson.fromJson(json, OperationRand.class);

    System.out.println(res);
	

[EDIT]for the Changing operation_rand
I would use the object for the nonchanging Fields


    import lombok.*;
    
    @Setter
    @Getter
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Key {
    int key1;
    int key2;
    }

in the main


    Gson gson = new Gson();
    Map&lt;String,Key&gt; rest = gson.fromJson(json,HashMap.class);
    System.out.println(rest);

答案2

得分: 0

100 不是 Map<String, Integer>。

也许使用 Map<String, Object> 而不是 Map<String, Map<String, Integer>>

通过 instanceof Integerinstanceof Map 来确定类型。

英文:

100 is not Map<String, Integer>.

Maybe use Map&lt;String,Object&gt; instead of Map&lt;String, Map&lt;String, Integer&gt;&gt;.

By instanceof Integerinstanceof Map to determine the type.

答案3

得分: 0

你只需将类简化如下:

public class Operation {
    @JsonProperty("operation_rand")
    private Map operationDetails;
    
    public Map getOperation() {
        return operationDetails;
    }
}
英文:

You just need to simplify the class like this:

public class Operation {
    @JsonProperty(&quot;operation_rand&quot;)
    private Map operationDetails;
    
    public Map getOperation() {
        return operationDetails;
    }
} 

huangapple
  • 本文由 发表于 2020年9月23日 14:13:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/64022021.html
匿名

发表评论

匿名网友

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

确定