JSON-B 通过设置 withNullValues(true) 使用适配器序列化 NPE

JSON-B hitting NPE serializing with adapter though setting withNullValues(true)

问题

JSON-B 用户指南建议 here 我应该能够使用我的代码序列化 null 值:

    Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
            .withNullValues(true)
            .withAdapters(new StatusAdapter()));

    jsonb.toJson(status,Status.class);

这里StatusAdapter是我自己的JsonbAdapter impl序列化app的Status class 看起来像这样:

状态适配器

@Override
public JsonObject adaptToJson(Status status) throws Exception {

   // ... 

   return Json.createObjectBuilder()

            .add("field1", status.getField1())               
            .add("field2", status.getField2())               

             // ... continues ...

            .build();

但是当这些吸气剂之一 returns null 时,我最终得到如下异常:

Caused by: java.lang.NullPointerException: Value in JsonObjects name/value pair cannot be null at org.glassfish.json.JsonObjectBuilderImpl.validateValue(JsonObjectBuilderImpl.java:222) at org.glassfish.json.JsonObjectBuilderImpl.add(JsonObjectBuilderImpl.java:90) at mypkg.StatusAdapter.adaptToJson(StatusAdapter.java:47) at mypkg.StatusAdapter.adaptToJson(StatusAdapter.java:14) at org.eclipse.yasson.internal.serializer.AdaptedObjectSerializer.serialize(AdaptedObjectSerializer.java:103)

pom.xml

我使用了 最新版本 来自 JSON-B Getting Started 页面的 Maven 依赖项:

            <dependency>
                    <groupId>javax.json.bind</groupId>
                    <artifactId>javax.json.bind-api</artifactId>
                    <version>1.0</version>
            </dependency>

            <dependency>
                    <groupId>org.eclipse</groupId>
                    <artifactId>yasson</artifactId>
                    <version>1.0.2</version>
            </dependency>

            <dependency>
                    <groupId>org.glassfish</groupId>
                    <artifactId>javax.json</artifactId>
                    <version>1.1.3</version>
            </dependency>

问题

所以我误解了API?或者这是 JSON 相关库的错误组合?其中一个有错误?

我也意识到,序列化 null 可能会在反序列化时给我带来第二个问题。如果这有助于指导答案,我将要使用 JSON-B 稍后反序列化。谢谢。

更新:

yasson issue 表明它可能是一个错误。在那里添加了更多细节。

你得到的异常基本上告诉你你不能将 null 传递给 JsonObjectBuilder#add 方法,这是由 JSONP 实现抛出的 org.glassfish:javax.json.

设置JsonbConfig#withNullValues(true)与此无关

JSONB 和 JSONP 是两个不同的 API,即便如此 JSONB 确实依赖于 JSONP。 org.eclipse:yasson 是 JSONB API 的一个实现,在您的情况下确实使用了 org.glassfish:javax.json - JSONP API 的一个实现,因为您在 POM 中提供了它。

设置 JsonbConfig#withNullValues(true) 是对 JSONB API 的调用,这确实意味着 "print null values to JSON" 例如:

{ firstname: null, lastname: null }

因此,当 org.eclipse:yasson (JSONB) 在 pojo 对象 属性 中遇到空值时,它会执行类似 javax.json.stream.JsonGenerator#writeNull(key).

的操作

这与您在 StatusAdapter 中的代码没有任何关系,它基本上是使用空值调用 JSONP API JsonObjectBuilder#add,这是不允许的。