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>
, В противном случае неизменные откажутся от особого режима Факультативного.
После этого все просто работало хорошо.