JSON in Java the Right Way -- Action, Jackson!
I'm trying to create a read only property id but it not working.
public class TestReadOnlyJson {
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
User user = new User(new BigInteger("69"), "Parent");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationConfig.Feature.AUTO_DETECT_FIELDS, false);
mapper.setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.NONE);
System.out.println("Before: " + user);
System.out.println();
String json = mapper.writeValueAsString(user);
user = null;
System.out.println("Json: " + json);
System.out.println();
user = ObjectMapperFac.createObjectMapper().readValue(json, User.class);
System.out.println("After: " + user);
}
}
class User {
private BigInteger id;
private String name;
private User() {
}
public User(BigInteger id, String name) {
this();
System.out.println("Constructor");
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Id:" + id + " Name: " + name;
}
@JsonIgnore
public void setId(BigInteger id) {
System.out.println("Setter");
this.id = id;
}
@JsonProperty
public BigInteger getId() {
return id;
}
}
Somebody knows why?
Tags:
Permalink Reply by Bruno Hansen on February 12, 2012 at 8:59am Though I've made User class public, Jackson is complaining about id property be private.
Is it right?
Permalink Reply by Tatu Saloranta on February 12, 2012 at 11:18am Complaining how? By an exception? If you disable Jackson's ability to change access rights, yes, you then must make things everything public. Or just enable feature to force things to be accessible - the only reason to disable this is on platforms where forcing fails for some reason (like some Google's messed-up systems). But from performance perspective access forcing should have no measurable impact, unlike reflection access itself.
Permalink Reply by Bruno Hansen on February 12, 2012 at 12:17pm By an exception...
I would like to make id property read only and ignore it like an unknown property.
I've tried to do it this way:
mapper.configure(DeserializationConfig.Feature.CAN_OVERRIDE_ACCESS_MODIFIERS, false);
private BigInteger id;
@JsonIgnore
public void setId(BigInteger id)
@JsonProperty
public BigInteger getId()
Permalink Reply by Tatu Saloranta on February 12, 2012 at 3:53pm I have pointed out multiple times that disabling CAN_OVERRIDE_ACCESS_MODIFIERS makes no sense here, so do not disable it. See [http://wiki.fasterxml.com/JacksonFeaturesSerialization] for more explanation.
Setter and getter annotations are correct. Add @JsonIgnore to 'private BigInteger id;' as well to make sure it will not be included. If you do want to pass id value via constructor, annotate that constructor with @JsonCreator, and add @JsonProperty for all parameters so Jackson knows which JSON properties to map to which argument.
Permalink Reply by Bruno Hansen on February 13, 2012 at 4:00am Yes, you've pointed out it so many times. I'm sorry about this.
Last question!
If I disable CAN_OVERRIDE_ACCESS_MODIFIERS, why not treat private and propected properties as a unknown propertie?
Permalink Reply by Tatu Saloranta on February 13, 2012 at 1:38pm That is a reasonable suggestion for an improvement. The reason really is that features evolved separately: this particular feature was added after introspection was implemented, and no cross-correlation was added. But it would make sense to try to combine feature sets; I agree that it does not make sense to try to call things that are not visible.
The only concern would be whether users would find it odd, in cases where annotations (like @JsonProperty) are used on non-public things, but are not found. Maybe that should then trigger an exception or such.
Anyway, feel free to file a Jira RFE; as I said, this is a good suggestion.
© 2013 Created by Tatu Saloranta.
Powered by