jsonb:Jsonb 未调用嵌套序列化
jsonb: nested serializing not called by Jsonb
新标签请求:java-ee-8
它有一个新功能,叫做 jsonb。使用 jsonb,我无法进行嵌套序列化。请参阅下面的粗体字。
所以,我写了一个jaxrs-application。这个应用程序有一个使用 jsonb 的 messagebodywriter:
final JsonbConfig defaultConfig = new JsonbConfig()
.withFormatting(Boolean.TRUE)
.withNullValues(Boolean.TRUE)
.withSerializers(
new QueryParamEntrySerializer(),
new ApiResponseDtoSerializer())
.withAdapters(new ResponseStatusJsonbAdapter());
final Jsonb jsonb = JsonbBuilder.create(defaultConfig);
ApiResponseDto 如下所示:
@Value.Immutable
@JsonbTypeSerializer(ApiResponseDtoSerializer.class)
public interface ApiResponseDto {
ResponseStatus status();
String message();
Optional<? extends Object> data();
}
ResponseStatus 是一个枚举,可以通过上面的 TypeAdapter 进行序列化。
为此 class 我编写了 ApiResponseDtoSerializer。
@Provider
public class ApiResponseDtoSerializer implements JsonbSerializer<ImmutableApiResponseDto> {
@Override
public void serialize(
final ImmutableApiResponseDto obj,
final JsonGenerator generator,
final SerializationContext ctx) {
generator.writeStartObject();
ctx.serialize("status", obj.status(), generator);
ctx.serialize("data", obj.data(), generator);
ctx.serialize("message", obj.message(), generator);
generator.writeEnd();
}
}
现在 Optional data() 应包含 QueryParamEntry 的 ImmutableSet,如下所示:
@Value.Immutable
@JsonbTypeSerializer(ImmutableQueryParamEntrySerializer.class)
public interface QueryParamEntry {
@Value.Parameter
String key();
@Value.Parameter
Optional<String> value();
}
类型适配器是这个:
@Provider
public class ImmutableQueryParamEntrySerializer implements JsonbSerializer<ImmutableQueryParamEntry> {
private static final Logger LOG = LoggerFactory.getLogger(ImmutableQueryParamEntrySerializer.class);
@Override
public void serialize(
final ImmutableQueryParamEntry obj,
final JsonGenerator generator,
final SerializationContext ctx) {
generator.writeStartObject();
LOG.debug("Writing: key = [{}].", obj.key());
ctx.serialize("key", obj.key(), generator);
ctx.serialize("value", obj.value(), generator);
generator.writeEnd();
}
}
最终输出为:
{
"status": "success",
"data": [
{
"key": null,
"value": null
}
],
"message": "Returning query param values."
}
如您所见,嵌套序列化不起作用。 Jsonb 似乎找到了正确的类型(否则它根本不会序列化对象)。但即使是我的 SerializerClass 中的日志语句也从未被调用。
顺便说一句:你需要 Guava 22 和 immutables.github.io 来编译这段代码,显然还有 slf4j:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.2.Final</version>
<scope>provided</scope>
</dependency>
<!-- JSON-P API -->
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.json.bind/javax.json.bind-api -->
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
这就是让它发挥作用的方法。
我摆脱了自定义序列化程序。正如我的评论中提到的,它们在未发布的 1.0.3 版本之前就已经损坏了。
相反,将您的方法重命名为 getStatus()
、getMessage()
和 getData()
(注意 get
-前缀)。
对于 getData();
,return 只是一个 Optional<Object>
,而不是 Optional<? extends Object>
。否则,不可变对象将拒绝 Optional 的特殊处理。
在那之后,一切都很好。
新标签请求:java-ee-8
它有一个新功能,叫做 jsonb。使用 jsonb,我无法进行嵌套序列化。请参阅下面的粗体字。
所以,我写了一个jaxrs-application。这个应用程序有一个使用 jsonb 的 messagebodywriter:
final JsonbConfig defaultConfig = new JsonbConfig()
.withFormatting(Boolean.TRUE)
.withNullValues(Boolean.TRUE)
.withSerializers(
new QueryParamEntrySerializer(),
new ApiResponseDtoSerializer())
.withAdapters(new ResponseStatusJsonbAdapter());
final Jsonb jsonb = JsonbBuilder.create(defaultConfig);
ApiResponseDto 如下所示:
@Value.Immutable
@JsonbTypeSerializer(ApiResponseDtoSerializer.class)
public interface ApiResponseDto {
ResponseStatus status();
String message();
Optional<? extends Object> data();
}
ResponseStatus 是一个枚举,可以通过上面的 TypeAdapter 进行序列化。 为此 class 我编写了 ApiResponseDtoSerializer。
@Provider
public class ApiResponseDtoSerializer implements JsonbSerializer<ImmutableApiResponseDto> {
@Override
public void serialize(
final ImmutableApiResponseDto obj,
final JsonGenerator generator,
final SerializationContext ctx) {
generator.writeStartObject();
ctx.serialize("status", obj.status(), generator);
ctx.serialize("data", obj.data(), generator);
ctx.serialize("message", obj.message(), generator);
generator.writeEnd();
}
}
现在 Optional data() 应包含 QueryParamEntry 的 ImmutableSet,如下所示:
@Value.Immutable
@JsonbTypeSerializer(ImmutableQueryParamEntrySerializer.class)
public interface QueryParamEntry {
@Value.Parameter
String key();
@Value.Parameter
Optional<String> value();
}
类型适配器是这个:
@Provider
public class ImmutableQueryParamEntrySerializer implements JsonbSerializer<ImmutableQueryParamEntry> {
private static final Logger LOG = LoggerFactory.getLogger(ImmutableQueryParamEntrySerializer.class);
@Override
public void serialize(
final ImmutableQueryParamEntry obj,
final JsonGenerator generator,
final SerializationContext ctx) {
generator.writeStartObject();
LOG.debug("Writing: key = [{}].", obj.key());
ctx.serialize("key", obj.key(), generator);
ctx.serialize("value", obj.value(), generator);
generator.writeEnd();
}
}
最终输出为:
{
"status": "success",
"data": [
{
"key": null,
"value": null
}
],
"message": "Returning query param values."
}
如您所见,嵌套序列化不起作用。 Jsonb 似乎找到了正确的类型(否则它根本不会序列化对象)。但即使是我的 SerializerClass 中的日志语句也从未被调用。
顺便说一句:你需要 Guava 22 和 immutables.github.io 来编译这段代码,显然还有 slf4j:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.2.Final</version>
<scope>provided</scope>
</dependency>
<!-- JSON-P API -->
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.json.bind/javax.json.bind-api -->
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
这就是让它发挥作用的方法。
我摆脱了自定义序列化程序。正如我的评论中提到的,它们在未发布的 1.0.3 版本之前就已经损坏了。
相反,将您的方法重命名为 getStatus()
、getMessage()
和 getData()
(注意 get
-前缀)。
对于 getData();
,return 只是一个 Optional<Object>
,而不是 Optional<? extends Object>
。否则,不可变对象将拒绝 Optional 的特殊处理。
在那之后,一切都很好。