0

新标签请求:java-ee-8

它有一个新功能,称为 jsonb。使用 jsonb,我无法让嵌套序列化工作。请参阅下面打印的粗体。

所以,我写了一个 jaxrs 应用程序。这个应用程序有一个使用 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 进行序列化。对于这个类,我编写了 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>
4

1 回答 1

0

所以这就是使它工作的必要条件。

我摆脱了自定义序列化程序。正如我在评论中提到的,无论如何,它们在未发布的 1.0.3 版本之前就被破坏了。

相反,将您的方法重命名为getStatus(),getMessage()getData()(注意get-Prefix)。对于getData();, 只返回一个Optional<Object>, 而不是Optional<? extends Object>. 否则,不可变对象将拒绝 Optional 的特殊处理。

在那之后,一切都运作良好。

于 2018-12-12T10:58:34.080 回答