【问题标题】:Parse JSON to java object when same field name occur in nested JSON当嵌套 JSON 中出现相同的字段名称时,将 JSON 解析为 java 对象
【发布时间】:2019-03-28 08:49:13
【问题描述】:

下面是我的 JSON:

{
  "time":{
    "date":{
      "year":2017,
      "month":3,
      "day":12
     },
    "time":{
      "hour":10,
      "minute":42,
      "second":42,
      "nano":810000000
     }
   },
"name":"Jon",
"message":{
"product":"orange"
"price":2000
}
}

'time' 字段有一个嵌套的 'time' 字段。如何使用jackson将其解析为java对象。谁能告诉我正确的方法?

【问题讨论】:

  • 解析成 POJO 还是 Map?您可以在 SO(herehere)或 in a source of your choice 上轻松找到 2000 多个答案。
  • 我找到了很多答案,但我没有找到任何包含将 JSON 转换为 POJO 的“同名嵌套字段”
  • 好的,抱歉,我不明白你只想要内部的time 属性。您可以将所有内容解析为 JsonNode,将内部属性作为 JsonNode 并将其解析为您的 POJO(请参阅我的答案)。
  • 如果您陷入其他JSON 结构,您始终可以使用在线工具生成POJO 模型,如本问题所述:Array of JSON Object to Java POJO

标签: java json parsing jackson gson


【解决方案1】:

您可以创建如下类:

class JavaObject {
    private TimeObject time;
    private String name;
    //other fields
    //getters and setters
}

class TimeObject {
    private Date date;
    private Time time;
    //getters and setters
}

class Date {
    private int year;
    private int month;
    private int day;
    //getters and setters
}

class Time {
    private int hour;
    private int minute;
    private int second;
    private long nano;
    //getters and setters
}

完成后,您可以使用Jacksonjson 字符串反序列化为JavaObject 对象,例如:

ObjectMapper objectMapper = new ObjectMapper();
JavaObject javaObject = objectMapper.readValue("{\n" + 
        "  \"time\":{\n" + 
        "    \"date\":{\n" + 
        "      \"year\":2017,\n" + 
        "      \"month\":3,\n" + 
        "      \"day\":12\n" + 
        "     },\n" + 
        "    \"time\":{\n" + 
        "      \"hour\":10,\n" + 
        "      \"minute\":42,\n" + 
        "      \"second\":42,\n" + 
        "      \"nano\":810000000\n" + 
        "     }\n" + 
        "   },\n" + 
        "\"name\":\"Jon\"}", JavaObject.class);
System.out.println(javaObject);

【讨论】:

  • 如果他们只需要来自内部 time 属性的数据,这似乎是一个很大的开销。还是我弄错了要求?
  • 非常感谢。你能帮我做一件事吗?有时时间字段分别带有小时,分钟,秒,有时它直接以字符串形式出现,例如“10:42:42:810000000”。在那种情况下,我该如何创建 Time 类?
【解决方案2】:

如果您只需要内部 time 对象,您可以快速完成:

// your POJO class
// (public fields sould be private with getter & setter, of course)

public class Pojo {
    public int hour;
    public int minute;
    public int second;
    public long nano;

    @Override
    public String toString() {
        return hour + ":" + minute + ":" + second + ":" + nano;
    }
}

然后:

//your json string
String jsonString = "{\"time\":{\"date\":{\"year\":2017,\"month\":3,\"day\":12},"
                + "\"time\":{\"hour\":10,\"minute\":42,\"second\":42,\"nano\":810000000}},"
                + "\"name\":\"Jon\",\"message\":{\"product\":\"orange\",\"price\":2000}}";

ObjectMapper mapper = new ObjectMapper();
JsonNode jsonRoot = mapper.readTree(jsonString); //parse string to JsonNode
Pojo pojo = mapper.treeToValue(jsonRoot.at("/time/time"), Pojo.class); //create Pojo instance from inner time object
System.out.println(pojo); //see if it worked

打印出来:

10:42:42:810000000

【讨论】:

  • 非常感谢。你能帮我做一件事吗?有时时间字段分别带有小时、分钟、秒,有时它直接以字符串形式出现,如“10:42:42:810000000”。在那种情况下我该如何解析它?
  • @user812142 我不太明白你的问题。 10:42:42:810000000 只是一个在 POJO 的 toString() 方法中构造的字符串。我添加它只是为了向您展示证明数据存在的输出。如果您的 Json 不包含 minutehour,则不会设置这些值(并保留默认值,因此在这种情况下为 0,但您可以更改)。
【解决方案3】:

使用Jackson library

ObjectMapper jsonMapper= new ObjectMapper();
YourCorrespondingObject object = jsonMapper.readValue("your json as string...", YourCorrespondingObject.class);

首先构建您的对象、填充它并转换为字符串会更容易,以确保它等于您现有的字符串,例如:

String jsonInString = mapper.writeValueAsString(object);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 2018-06-30
    • 1970-01-01
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多