【问题标题】:Why jackson is serializing transient member also?为什么杰克逊还要序列化瞬态成员?
【发布时间】:2014-03-11 19:42:12
【问题描述】:

我正在使用 Jackson 2.1.4 将 POJO 序列化为 JSON,但我想忽略特定字段以使其序列化。我使用了瞬态,但它仍在序列化该元素。

public class TestElement {

    int x;

    private transient String y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public String getY() {
        return y;
    }

    public void setY(String y) {
        this.y = y;
    }
}

我正在序列化如下:

public static void main(String[] args) throws JsonProcessingException {
    TestElement testElement = new TestElement();
    testElement.setX(10);
    testElement.setY("adasd");
    ObjectMapper om = new ObjectMapper();
    String serialized = om.writeValueAsString(testElement);
    System.err.println(serialized);
}

请不要建议@JsonIgnore,因为我不想将我的模型与杰克逊特定的注释联系起来。只能使用瞬态来完成吗? objectmapper 上是否有任何用于可见性设置的 API?

【问题讨论】:

    标签: json jackson transient


    【解决方案1】:

    Jackson 序列化 transient 成员的原因是因为 getter 用于确定要序列化的内容,而不是成员本身 - 而且由于 y 有一个公共 getter,它会被序列化。 如果您想更改该默认设置并让 Jackson 使用字段 - 只需执行以下操作:

    om.setVisibilityChecker(
      om.getSerializationConfig()
        .getDefaultVisibilityChecker()
        .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
        .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
    );
    

    另一种忽略序列化属性的方法是直接在类上进行:

    @JsonIgnoreProperties(value = { "y" })
    public class TestElement {
    ...
    

    还有一种方式是直接上场:

    public class TestElement {
    
        @JsonIgnore
        private String y;
    ...
    

    希望这会有所帮助。

    【讨论】:

    • 正如我在问题中提到的,我更喜欢一种不必将我的模型与杰克逊特定注释联系起来的方式。我不明白的一件事是为什么杰克逊要序列化甚至是临时成员?其他 API,如 Smart JSON 甚至 java 序列化程序都不会这样做。对此有任何想法吗?
    • 我更新了我的原始答案以进一步解释问题并为您提供解决方案 - 希望对您有所帮助。
    • 谢谢,我正在寻找第一个解决方案。现在我可以做到这一点,而不必使用所有杰克逊特定的注释。
    • 不用担心 - 实际上还有其他一些方法可以做到这一点 - 你可以在这里查看我关于忽略某些字段的帖子:baeldung.com/jackson-ignore-properties-on-serialization - 很高兴我能提供帮助。干杯。
    • 这是另一种方法(建议作为编辑):om.disable(MapperFeature.AUTO_DETECT_GETTERS) om.disable(MapperFeature.AUTO_DETECT_IS_GETTERS) om.enable(MapperFeature.AUTO_DETECT_FIELDS)
    【解决方案2】:

    我无法让 cmets 在这里完成之前的响应,更改(现在)已弃用的方法 setVisibilityChecker 并为布尔值添加缺少的子句:

    mapper.setVisibility(
        mapper.getSerializationConfig().
        getDefaultVisibilityChecker().
        withFieldVisibility(JsonAutoDetect.Visibility.ANY).
        withGetterVisibility(JsonAutoDetect.Visibility.NONE).
        withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
    );
    

    【讨论】:

      【解决方案3】:

      阻止 Jackson 序列化和反序列化的新方法是调用 mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)

      【讨论】:

      • 这被证实可以在 Kotlin 版本 1.2.71 上使用 Kotlin 的 @Transient 注解。
      【解决方案4】:

      您可以使用弹簧属性对其进行配置

      spring.jackson.mapper.propagate-transient-marker=true
      

      【讨论】:

        猜你喜欢
        • 2012-12-27
        • 2015-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多