Json 嵌套对象检查是否为空
Json nested Objects check if null
考虑以下 json
{
"sub1":{
"name":"Name-sub1",
"sub11":{
"name":"Name-sub11",
"sub111":{
"name":"Name-sub111",
...
},
..
},
...
},
...
}
我现在想获取 java 中的内部名称元素 (Name-sub111)(它是 io.vertx.core.json.JsonObject)
object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name")
但我不确定 sub1 或 sub11 或 sub111 是否存在 - 所以我总是需要检查 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");
}
有人知道这种情况的更好解决方案吗?
可能不是最好的解决方案,因为这个异常也可能是由于其他原因引起的。
try {
object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name")
} catch(NullpointerException e) {
// handle error
}
这里的一个选项是使用Java 8 Optional,它消除了重复的方法调用。但是,对于某些人来说,最终结果可能看起来不够清晰:
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")
)));
您可能需要考虑创建一些 return Optional
对象的辅助方法。
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));
}
然后您可以编写方法来实现所需的结果。
try {
return getJsonObject(obj, "sub1").map((obj) -> getJsonObject(obj, "sub2")).map((obj) -> getString(obj, "sub3")).get();
} catch (NoSuchElementException e) {
return null;
}
如果它不是 one-time 解析的东西,你可以将你的 json 映射到 java 对象并使用 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;
}
}
简单而有效的解决方案,使用减少:
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;
考虑以下 json
{
"sub1":{
"name":"Name-sub1",
"sub11":{
"name":"Name-sub11",
"sub111":{
"name":"Name-sub111",
...
},
..
},
...
},
...
}
我现在想获取 java 中的内部名称元素 (Name-sub111)(它是 io.vertx.core.json.JsonObject)
object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name")
但我不确定 sub1 或 sub11 或 sub111 是否存在 - 所以我总是需要检查 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");
}
有人知道这种情况的更好解决方案吗?
可能不是最好的解决方案,因为这个异常也可能是由于其他原因引起的。
try {
object.getJsonObject("sub1").getJsonObject("sub11").getJsonObject("sub111").getString("name")
} catch(NullpointerException e) {
// handle error
}
这里的一个选项是使用Java 8 Optional,它消除了重复的方法调用。但是,对于某些人来说,最终结果可能看起来不够清晰:
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")
)));
您可能需要考虑创建一些 return Optional
对象的辅助方法。
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));
}
然后您可以编写方法来实现所需的结果。
try {
return getJsonObject(obj, "sub1").map((obj) -> getJsonObject(obj, "sub2")).map((obj) -> getString(obj, "sub3")).get();
} catch (NoSuchElementException e) {
return null;
}
如果它不是 one-time 解析的东西,你可以将你的 json 映射到 java 对象并使用 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;
}
}
简单而有效的解决方案,使用减少:
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;