In My CXF-based REST layer I am using Jackson for seializing/deserializing Groovy objects. The issue I am experiencing deals with deserializing a property that does not have a setter method. There is a domain object Dashboard with getGroups() method returning a list of Group objects. Upon serialization this object is properly converted to JSON with "group" attribute. When I send the object for update from JavaScript, JSON still has the "group" attribute. Since the property is read-only on the domain object I would like to simply ignore the "group" property when deserializing JSON.
Since I am using Jackson mix-ins, I tried various combination of @JsonIgnore, @JsonGetter and @JsonProperty annotations - all to no avail. If the property is available upon serialization, I get the error below in deserialization. I can clean the JSON object in JavaScript by removing the "group" attribute, bit I would like to find a server-side solution.
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)
How can I tell Jackson to ignore a read-only property on deserialization?
Thank you,
Michael
public class JsonMappingException extends JsonProcessingException. Checked exception used to signal fatal problems with mapping of content, distinct from low-level I/O problems (signaled using simple IOException s) or data encoding/decoding problems (signaled with JsonParseException , JsonGenerationException ).
Jackson uses default (no argument) constructor to create object and then sets value using setters. so you only need @NoArgsConstructor and @Setter.
If there are fields in Java objects that do not wish to be serialized, we can use the @JsonIgnore annotation in the Jackson library. The @JsonIgnore can be used at the field level, for ignoring fields during the serialization and deserialization.
After many fruitless hours, I have finally found the magic combination of spells that addresses such a seemingly trivial issue. In the mixin I had to create this combination of annotations:
@JsonIgnore
abstract Set<Group> groups
@JsonProperty
abstract Set<Group> getGroups()
@JsonIgnore
abstract void setGroups(Set<Group> groups)
On top of that I had to add two configuration parameters to the ObjectMapper:
mapper.configure(MapperFeature.USE_GETTERS_AS_SETTERS, false)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
Isn't there a simpler way to achieve the same?
Michael
I had the same issue. Solution was to give the getter the correct name:
List list...
setList(...)
was correct, but my getter was
setProductList()
which produced the "setterLess" error. changing it to:
setList(...)
resolved the issue
I just ran into the same problem, and my solution was to create a private, no-op setter:
public class MyFoo {
public String getMyStr() {
return "hello, world";
}
private void setMyStr(String ignored) {}
}
Making setMyStr
private prevents me from accidentally trying to call it from my code, but Jackson still finds it and invokes it. Little does jackson know -- or care -- that invoking it does nothing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With