英文:
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 "key1" and "key2".
{
"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<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 = 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<String, Integer>`
</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("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 From Google
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
Then,
String json ="{\n" +
" \"operation_rand\":\n" +
" {\n" +
" \"key1\": 1005, \n" +
" \"key2\": 5\n" +
" }\n" +
"}";
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<String,Key> 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 Integer
、instanceof Map
来确定类型。
英文:
100 is not Map<String, Integer>.
Maybe use Map<String,Object>
instead of Map<String, Map<String, Integer>>
.
By instanceof Integer
、instanceof 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("operation_rand")
private Map operationDetails;
public Map getOperation() {
return operationDetails;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论