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
,这是不允许的。
问题
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
,这是不允许的。