如何使用 Jackson 解析 JSON 对象数组?
How to parse a JSON array of objects using Jackson?
我有一个 Json 回复如下:
{
"data": {
"date": "7 Apr 2022",
"employee": [
{
"id": [
"1288563656"
],
"firstname": [
"Mohammed"
],
"lastname": [
"Ali"
]
}
]
}
}
我正在尝试创建一个名为 Employee 的 POJO 并将其映射到 JSON 响应中的“employee”属性。
这是我尝试做的:
Employee.java
public class Emoloyee {
private Integer[] id;
private String[] firstname;
private String[] lastname;
public Employee(Integer[] id, String[] firstname, String[] lastname){
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
}
public Employee(){
}
public Integet[] getId(){
return id;
}
public void setId(Integer[] id){
this.id = id;
}
public String[] getFirstname(){
return firstname;
}
public void setFirstname(String[] firstname){
this.firstname = firstname;
}
public String[] getLastname(){
return lastname;
}
public void setLastname(String[] lastname){
this.lastname = lastname;
}
}
使用杰克逊:
ObjectMapper mapper = new ObjectMapper();
URL jsonUrl = new URL("[API_URL]");
final ObjectNode node = mapper.readValue(jsonUrl, ObjectNode.class);
Employee[] employees = mapper.treeToValue(node.get("data").get("employee"), Employee[].class);
当我执行应用程序时,出现以下错误:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type 'long' from Array value (toke 'JsonToken.START_ARRAY')
您可能已经注意到,我对 date 属性不感兴趣,我只需要获取员工的值并从中创建一个 Employee 对象。
Employee
POJO 应该如下所示:
@JsonProperty("id")
private final List<String> ids;
@JsonProperty("firstname")
private final List<String> firstNames;
@JsonProperty("lastname")
private final List<String> lastNames;
@JsonCreator
public Employee(@JsonProperty(value = "id") List<String> ids, @JsonProperty(value = "firstname") List<String> firstNames, @JsonProperty(value = "lastname") List<String> lastNames) {
this.ids = ids;
this.firstNames = firstNames;
this.lastNames = lastNames;
}
//getters code
那么,你有一个对象Data
:
@JsonProperty("date")
private final String date;
@JsonProperty("employee")
private final List<Employee> employees;
@JsonCreator
public Data(@JsonProperty(value = "date") String date, @JsonProperty(value = "employee") List<Employee> employees) {
this.date = date;
this.employees = employees;
}
//getters code
最后,您要解析的整个 Answer
具有以下形状:
@JsonProperty("data")
private final Data data;
@JsonCreator
public Answer(@JsonProperty(value = "data") Data data) {
this.data = data;
}
//getter code
一旦你定义了这 3 个类,那么你将能够做到:
ObjectMapper objectMapper = new ObjectMapper();
Answer answer = objectMapper.readValue(yourStringAnswer, Answer.class);
注意:在您的问题中,您试图将 URL
解析为 ObjectNode
。我几乎不怀疑你能做到这一点。
我猜您想对 URL
执行 HTTP 请求,然后获取响应流,这就是您要解析为 Answer
的内容(而不是 URL 本身)。
此外,关于 API 回复的一些说明(如果您拥有它并可以根据它采取行动):
- 所有列表将更自然地用复数名称声明(例如
employee
应该是 employees
)
ids
的列表是数字,但作为字符串返回。另外,为什么员工会有一个 ID 列表,而不是一个 ID?
- 为什么员工会有名字和姓氏列表?这不应该是每个简单的字符串(即使由多个名称组成)吗?
- 使用驼峰式大小写(
firstName
,而不是 firstname
)
- 我看不出将所有内容都放入
data
的意义,它可能只是包含 date
和 employees
的响应
我有一个 Json 回复如下:
{
"data": {
"date": "7 Apr 2022",
"employee": [
{
"id": [
"1288563656"
],
"firstname": [
"Mohammed"
],
"lastname": [
"Ali"
]
}
]
}
}
我正在尝试创建一个名为 Employee 的 POJO 并将其映射到 JSON 响应中的“employee”属性。
这是我尝试做的:
Employee.java
public class Emoloyee {
private Integer[] id;
private String[] firstname;
private String[] lastname;
public Employee(Integer[] id, String[] firstname, String[] lastname){
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
}
public Employee(){
}
public Integet[] getId(){
return id;
}
public void setId(Integer[] id){
this.id = id;
}
public String[] getFirstname(){
return firstname;
}
public void setFirstname(String[] firstname){
this.firstname = firstname;
}
public String[] getLastname(){
return lastname;
}
public void setLastname(String[] lastname){
this.lastname = lastname;
}
}
使用杰克逊:
ObjectMapper mapper = new ObjectMapper();
URL jsonUrl = new URL("[API_URL]");
final ObjectNode node = mapper.readValue(jsonUrl, ObjectNode.class);
Employee[] employees = mapper.treeToValue(node.get("data").get("employee"), Employee[].class);
当我执行应用程序时,出现以下错误:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type 'long' from Array value (toke 'JsonToken.START_ARRAY')
您可能已经注意到,我对 date 属性不感兴趣,我只需要获取员工的值并从中创建一个 Employee 对象。
Employee
POJO 应该如下所示:
@JsonProperty("id")
private final List<String> ids;
@JsonProperty("firstname")
private final List<String> firstNames;
@JsonProperty("lastname")
private final List<String> lastNames;
@JsonCreator
public Employee(@JsonProperty(value = "id") List<String> ids, @JsonProperty(value = "firstname") List<String> firstNames, @JsonProperty(value = "lastname") List<String> lastNames) {
this.ids = ids;
this.firstNames = firstNames;
this.lastNames = lastNames;
}
//getters code
那么,你有一个对象Data
:
@JsonProperty("date")
private final String date;
@JsonProperty("employee")
private final List<Employee> employees;
@JsonCreator
public Data(@JsonProperty(value = "date") String date, @JsonProperty(value = "employee") List<Employee> employees) {
this.date = date;
this.employees = employees;
}
//getters code
最后,您要解析的整个 Answer
具有以下形状:
@JsonProperty("data")
private final Data data;
@JsonCreator
public Answer(@JsonProperty(value = "data") Data data) {
this.data = data;
}
//getter code
一旦你定义了这 3 个类,那么你将能够做到:
ObjectMapper objectMapper = new ObjectMapper();
Answer answer = objectMapper.readValue(yourStringAnswer, Answer.class);
注意:在您的问题中,您试图将 URL
解析为 ObjectNode
。我几乎不怀疑你能做到这一点。
我猜您想对 URL
执行 HTTP 请求,然后获取响应流,这就是您要解析为 Answer
的内容(而不是 URL 本身)。
此外,关于 API 回复的一些说明(如果您拥有它并可以根据它采取行动):
- 所有列表将更自然地用复数名称声明(例如
employee
应该是employees
) ids
的列表是数字,但作为字符串返回。另外,为什么员工会有一个 ID 列表,而不是一个 ID?- 为什么员工会有名字和姓氏列表?这不应该是每个简单的字符串(即使由多个名称组成)吗?
- 使用驼峰式大小写(
firstName
,而不是firstname
) - 我看不出将所有内容都放入
data
的意义,它可能只是包含date
和employees
的响应