jsonb 1.0 / eclipse yasson会忽略没有bean访问器方法的私有属性

时间:2019-02-06 13:55:44

标签: java json maven jsonb yasson

根据我假设的官方用户指南http://json-b.net/users-guide.html,该引擎应使用(或不使用)bean访问器方法来序列化找到的所有属性(我意识到Dog示例使用公共字段,但是请参见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 个答案:

答案 0 :(得分:0)

我在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();