当前位置: 首页 > 面试题库 >

JSR-353如何使用javax.json.JsonObjectBuilder添加空值

阚吕恭
2023-03-14
问题内容

AS javax.json文档建议使用提供的构建器来创建JsonObject的方法,例如:

JsonBuilderFactory factory = Json.createBuilderFactory(config);
 JsonObject value = factory.createObjectBuilder()
     .add("firstName", "John")
     .add("lastName", "Smith")
     .add("age", 25)
     .add("address", factory.createObjectBuilder()
         .add("streetAddress", "21 2nd Street")
         .add("city", "New York")
         .add("state", "NY")
         .add("postalCode", "10021"))
     .add("phoneNumber", factory.createArrayBuilder()
         .add(factory.createObjectBuilder()
             .add("type", "home")
             .add("number", "212 555-1234"))
         .add(factory.createObjectBuilder()
             .add("type", "fax")
             .add("number", "646 555-4567")))
     .build();

本示例为Give键添加值。在现实生活中,这些值可能源自某些(pojo)域对象,例如:

JsonBuilderFactory factory = Json.createBuilderFactory(config);
 JsonObject value = factory.createObjectBuilder()
     .add("firstname", customer.getFirstame())
     .add("lastname", customer.getLastame())
     .add("age", customer.getAge())
     ....

如果键或值为null,则JsonOBjectBuilder会引发NPE。如果客户没有注册年龄,则以上代码将引发NPE。

因此,基本上,对于我添加的每个字段,我都必须检查该值是否为null并添加实际值,否则不要添加该字段或为键添加JsonValue.NULL。这会导致很多(不需要的)样板…

就我而言,我最终得到了自定义的JsonUtils类,其中包括各种静态方法,例如:

public static void add(JsonObjectBuilder builder, String name, Long value) {
    if (value == null) {
        builder.add(name,  JsonValue.NULL);
    }
    else {
        builder.add(name, value);
    }
}

public static void add(JsonObjectBuilder builder, String name, String value) {
    if (value == null) {
        builder.add(name,  JsonValue.NULL);
    }
    else {
        builder.add(name, value);
    }
}

然后调用

builder = Json.createObjectBuilder();
JsonUtils.add(builder, "id", customer.getId());
JsonUtils.add(builder, "name", customer.getName());
JsonUtils.add(builder, "gender", customer.getGender());
builder.build()

但是某种程度上如果感觉不对。为什么javax.json没有提供更简单的方法来添加null值(如果没有其他样板的话),或者我错过了什么?

我批评JSR-353 api的主要观点是,尽管它看起来像是一个非常不错的 流利的 api(请参阅apidoc的示例),但实际上并非如此。


问题答案:

JsonObjectBuilder从工厂获取实现可能很困难,但是可以使其更简单。

创建一个JsonObjectBuilder装饰器类,检查以下内容null

public class NullAwareJsonObjectBuilder implements JsonObjectBuilder {
    // Use the Factory Pattern to create an instance.
    public static JsonObjectBuilder wrap(JsonObjectBuilder builder) {
      if (builder == null) {
        throw new IllegalArgumentException("Can't wrap nothing.");
      }
      return new NullAwareJsonObjectBuilder(builder);
    }

    // Decorated object per Decorator Pattern.
    private final JsonObjectBuilder builder;

    private NullAwareJsonObjectBuilder(JsonObjectBuilder builder) {
      this.builder = builder;
    }

    public JsonObjectBuilder add(String name, JsonValue value) {
      builder.add(name, (value == null) ? JsonValue.NULL : value);
    }

    // Implement all other JsonObjectBuilder methods.
    ..
}

以及如何使用它:

JsonObjectBuilder builder = NullAwareJsonObjectBuilder.wrap(
        factory.createObjectBuilder());
builder.add("firstname", customer.getFirstame())
    .add(...


 类似资料:
  • 我想使用新的JSR-353(用于JSON处理的JavaAPI)与大家分享我的问题/答案。具体地说,您可以在两种不同的“API”中操作JSON数据:流和对象API。 如果你在谷歌上输入“jsr-353教程”,你会得到很多结果。 https://jcp.org/en/jsr/detail?id=353~具体请求的详细信息。 https://jsonp.java.net/~API的主站点,还将您链接到此

  • 我在网上找不到我问题的答案(也许我搜索得不够好,因为我在这方面还是个新手)。 谁能告诉我Jackson和Gson是否实现了标准JSR353:Java™ 用于JSON处理的API。我想用标准代码写。

  • 问题内容: 如何使用Javascript 添加CSS规则(例如)? 问题答案: 您也可以使用DOM Level 2 CSS接口(MDN)执行此操作: …(除了(自然地)IE8和更早版本以外的所有版本),它使用自己的边际差异措辞: 与createElement-set- innerHTML方法相比,此方法具有理论上的优势,因为您不必担心在innerHTML中放置特殊的HTML字符,但实际上,样式元素

  • 问题内容: 如何使用Dockerfile添加用户-以下内容不起作用。 我完整的Dockerfile: 问题答案: 使用而非交互来添加用户。 以下命令不会创建user。 它将使用用户 请参考Dockerfile用户文档 USER指令设置运行映像时使用的用户名或UID,以及Dockerfile中跟随该映像的所有RUN,CMD和ENTRYPOINT指令。 注意: 确保这是默认外壳程序。 如果使用默认外壳

  • 我需要添加一些空间开始的第一项和结束的最后一项的回收,所以他们可以滚动到屏幕的边缘(因为他们不能与回收器视图的边距或填充) 问题是项目之间的间距应该不同,所以我不能只是将这个“空间”添加到项目布局中。现在,我正试图将ItemEdition添加到我的回收器中,但结果就是这样: 在我触摸它之前,行间距随机出现:随机行间距 然后,当我滚动到最后并返回时,所需的空间出现在屏幕上适合的最后一项之后,而不是在

  • 问题内容: 我试图在没有LTV格式的已签名PDF文档中启用LTV。在所有情况下,我都找到了相同的示例,如链接中所述。如何为时间戳签名启用LTV,启用iText LTV-如何添加更多CRL?,它定义了获得预期结果的过程。碰巧我没有工作,它没有给我任何错误,但是我没有添加LTV。 为什么在执行以下代码时不会给我任何错误,但是我不添加LTV的一些想法。 这是我尝试添加LTV的方法: 我正在使用的版本: