jsonb 1.0 / eclipse yasson игнорирует приватные свойства без методов доступа к bean-компонентам
Согласно официальному руководству пользователя, http://json-b.net/users-guide.html, механизм должен сериализовать любые свойства, которые он находит, с использованием методов доступа к компонентам или без них (я понимаю, что в примере с Dog используется public поля, но см. пример Person для личных полей).
Учитывая эти классы:
public class Rectangle {
private double length1 = 0.0;
@JsonbProperty("length2")
private double length2 = 0.0;
public double width = 0.0;
}
public class Rectangle2 {
@JsonbProperty
private double length = 0.0;
private double width = 0.0;
public double getLength() {
return length;
}
public double getWidth() {
return width;
}
}
Когда я сериализирую это так:
public class App2 {
public static void main(String... argv) {
Jsonb jsonb = JsonbBuilder.create();
System.out.println("Rectangle: " + jsonb.toJson(new Rectangle()));
System.out.println("Rectangle2: " + jsonb.toJson(new Rectangle2()));
}
}
Вывод такой:
Rectangle: {"width":0.0}
Rectangle2: {"length":0.0,"width":0.0}
Что я вижу, так это то, что в Rectangle сериализуется только ширина, потому что она общедоступна. length1 и length2 игнорируются, поскольку они являются частными, даже если для length2 существует аннотация свойства. Rectangle2 полностью сериализован, так как имеет методы bean.
Это должно быть так? Требование, чтобы я сделал все поля открытыми и изменяемыми для включения сериализации, кажется огромным ограничением.
Мои зависимости настроены так:
<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.4</version>
</dependency>
1 ответ
Я нашел эту ссылку о спецификации и видимости поля в источнике yasson (org.eclipse.yasson.internal.model.PropertyValuePropagation.DefaultVisibilityStrategy):
@Override
public boolean isVisible(Field field) {
//don't check field if getter is not visible (forced by spec)
if (method != null && !isVisible(method)) {
return false;
}
return Modifier.isPublic(field.getModifiers());
}
Я не могу говорить со спецификацией, но это совпадает с тем, что я видел - что поля будут сериализованы только на основе видимости метода getter.
Я хочу, чтобы моя сериализация была основана исключительно на полях, и только поля, которые я хочу сериализовать, - поэтому я выбрал собственный PropertyVisibilityStrategy, который не предоставляет никаких методов, а только поля с аннотацией JsonbProperty. Это дает мне большую часть того, что я хочу:
Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(
new JsonbConfig().withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() {
@Override
public boolean isVisible(Field field) {
return field.getAnnotation(JsonbProperty.class) != null;
}
@Override
public boolean isVisible(Method method) {
return false;
}
})
).build();