使用Jackson反序列化只读属性时出错



在我基于cxf的REST层中,我使用Jackson来序列化/反序列化Groovy对象。我遇到的问题是处理没有setter方法的属性的反序列化。有一个域对象Dashboard,其getGroups()方法返回Group对象列表。在序列化时,该对象被正确地转换为带有"group"属性的JSON。当我从JavaScript发送对象进行更新时,JSON仍然具有"group"属性。由于该属性在域对象上是只读的,所以我想在反序列化JSON时简单地忽略"group"属性。

因为我使用Jackson mix-ins,我尝试了@JsonIgnore, @JsonGetter和@JsonProperty注释的各种组合-都无济于事。如果属性在序列化时可用,则在反序列化时得到下面的错误。我可以通过删除"group"属性来清理JavaScript中的JSON对象,但我想找到一个服务器端解决方案。

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Problem deserializing 'setterless' property 'groups': get method returned null (through reference chain: org.ozoneplatform.commons.server.domain.model.DashboardTemplate["groups"])
at com.fasterxml.jackson.databind.deser.impl.SetterlessProperty.deserializeAndSet(SetterlessProperty.java:114)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:198)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:577)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:393)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:289)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1169)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:625)
at com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:448)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1038)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:614)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238)

如何告诉Jackson在反序列化时忽略只读属性?

谢谢你,迈克尔

经过许多毫无结果的小时后,我终于找到了解决这个看似微不足道的问题的魔法组合。在mixin中,我必须创建以下注解组合:

@JsonIgnore
abstract Set<Group> groups
@JsonProperty
abstract Set<Group> getGroups()
@JsonIgnore
abstract void setGroups(Set<Group> groups)

在此之上,我必须向ObjectMapper添加两个配置参数:

mapper.configure(MapperFeature.USE_GETTERS_AS_SETTERS, false)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

没有更简单的方法来达到同样的效果吗?

迈克尔

我也有同样的问题。解决方法是给getter一个正确的名字:

List list...
setList(...)

是正确的,但getter是正确的setProductList()产生"setless"错误。将其改为:setList(...)解决问题

我刚刚遇到了同样的问题,我的解决方案是创建一个私有的,无操作的setter:

public class MyFoo {
    public String getMyStr() {
        return "hello, world";
    }
    private void setMyStr(String ignored) {}
}

使setMyStr私有可以防止我意外地从代码中调用它,但是Jackson仍然找到它并调用它。jackson不知道——也不关心——调用它没有任何作用。

相关内容

最新更新