Json nested Objects check if null

≡放荡痞女 提交于 2019-12-11 09:22:27

问题


consider the following json

{  
   "sub1":{  
     "name":"Name-sub1",
     "sub11":{
       "name":"Name-sub11",
       "sub111":{
         "name":"Name-sub111",
         ...
       },
       ..
     },
     ...
   },
   ...
}

I now want to fetch the inner name Element (Name-sub111) in java (it's a io.vertx.core.json.JsonObject)

object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name")

But I'm not sure if sub1 or sub11 or sub111 even exist - so I always need to check for null

if(object.getJsonObject("sub1") != null && object.getJsonObject("sub1").getJsonObject("sub11") != null && object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111") != null) {
    return object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name");
}

Does someone know a better solutions for this case?


回答1:


an option here is to use Java 8 Optional, which eliminates the dupplicate method calls. Howewver, the end result might not look clear enough for some:

    return Optional.ofNullable(object.getJsonObject("sub1")).map(subObj1 -> 
        Optional.ofNullable(subObj1.getJsonObject("sub11")).map(subObj11 ->
            Optional.ofNullable(subObj11.getJsonObject("sub111")).map(subObj111 -> subObj111.getString("name") 
    )));



回答2:


You might want to consider creating some helper methods that return Optional objects.

public static Optional<JsonObject> getJsonObject(JsonObject obj, String prop) {
    return Optional.ofNullable(obj.getJsonObject(prop));
}

public static Optional<String> getString(JsonObject obj, String prop) {
    return Optional.ofNullable(obj.getString(prop));
}

Then you can compose the methods to achieve the desired result.

try {
    return getJsonObject(obj, "sub1").map((obj) -> getJsonObject(obj, "sub2")).map((obj) -> getString(obj, "sub3")).get();
} catch (NoSuchElementException e) {
    return null;
}



回答3:


If it's not one-time parsing thing, you can map your json to java object and use Optional class:

import io.vertx.core.json.JsonObject;

import java.util.Optional;

class Scratch {
  public static void main(String[] args) {
    String json = "{\n" +
            "  \"sub1\" : {\n" +
            "    \"name\" : \"Name-sub1\",\n" +
            "    \"sub11\" : {\n" +
            "      \"name\" : \"Name-sub11\",\n" +
            "      \"sub111\" : {\n" +
            "        \"name\" : \"Name-sub111\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

    JsonObject object = new JsonObject(json);    
    SamplePojo pojo = object.mapTo(SamplePojo.class);
    System.out.println(pojo);

    String sub111name = pojo.getSub1()
            .flatMap(Sub1::getSub11)
            .flatMap(Sub11::getSub111)
            .map(Sub111::getName)
            .orElse("");

    System.out.println(sub111name);
  }
}

class SamplePojo {
  private Sub1 sub1;

  public Optional<Sub1> getSub1() {
    return Optional.ofNullable(sub1);
  }

  public void setSub1(Sub1 sub1) {
    this.sub1 = sub1;
  }
}

class Sub1 {
  private String name;
  private Sub11 sub11;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Optional<Sub11> getSub11() {
    return Optional.ofNullable(sub11);
  }

  public void setSub11(Sub11 sub11) {
    this.sub11 = sub11;
  }
}

class Sub11 {
  private String name;
  private Sub111 sub111;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Optional<Sub111> getSub111() {
    return Optional.ofNullable(sub111);
  }

  public void setSub111(Sub111 sub111) {
    this.sub111 = sub111;
  }
}

class Sub111 {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}



回答4:


Simple yet efficient solution, using reduction:

List<String> nodesToTraverse = Arrays.asList("sub1", "sub11", "sub111");
JsonObject leaf = nodesToTraverse.stream().reduce(object,
          (obj, node) -> obj == null ? null : obj.getJsonObject(node),
          (prev, cur) -> cur);
return leaf != null ? leaf.getString("name") : null;



回答5:


Might not be the best solution, because this Exception could also be caused for another reason.

try {
    object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name")
} catch(NullpointerException e) {
   // handle error
}


来源:https://stackoverflow.com/questions/49518549/json-nested-objects-check-if-null

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!