为啥杰克逊还要序列化瞬态成员?
Posted
技术标签:
【中文标题】为啥杰克逊还要序列化瞬态成员?【英文标题】: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?
【问题讨论】:
【参考方案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
【讨论】:
以上是关于为啥杰克逊还要序列化瞬态成员?的主要内容,如果未能解决你的问题,请参考以下文章