jsonb: вложенная сериализация, не вызываемая Jsonb

Запрос нового тега: java-ee-8

У него есть новая функция, которая называется jsonb. С jsonb я не могу заставить работать вложенную сериализацию. См. Жирный шрифт ниже.

Итак, я написал jaxrs-приложение. В этом приложении есть автор сообщений, использующий jsonb:

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();
  }

}

Теперь Необязательные данные () должны содержать ImmutableSet из QueryParamEntry, например:

@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, кажется, находит правильный тип (потому что иначе он вообще не сериализует объект). Но даже оператор log из моего 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>

0 ответов

Итак, вот что нужно, чтобы это заработало.

Я избавился от пользовательских сериализаторов. Как уже упоминалось в моем комментарии, они все равно сломаны до неизданной версии 1.0.3.

Вместо этого переименуйте ваши методы в getStatus(), getMessage() а также getData() (обратите внимание на get-Префикс). За getData();Верни всего лишь Optional<Object>не Optional<? extends Object>, В противном случае неизменные откажутся от особого режима Факультативного.

После этого все просто работало хорошо.

Другие вопросы по тегам