I am using Robospice + Retrofit + Jackson. I have not plain class which has another class object as a field. I need to parse json and create class with field.
Here is my class
@JsonIgnoreProperties(ignoreUnknown=true)
public class User implements UserInformationProvider {
@JsonProperty("customer_id")
public int id;
@JsonProperty("firstname")
public String firstName;
@JsonProperty("lastname")
public String lastName;
@JsonProperty("email")
public String email;
@JsonProperty("telephone")
public String phone;
@JsonProperty("token_api")
public String token;
@JsonProperty("token_expire")
public int tokenExpireTime;
public UserPreferences userPreferences;
@Override
public String getUserFirstName() {
return firstName;
}
@Override
public String getUserLastName() {
return lastName;
}
@Override
public String getUserEmail() {
return email;
}
@Override
public String getUserIconUrl() {
return null;
}
}
And preferences class
public class UserPreferences {
public boolean offersNotifications;
public boolean statusChangedNotifications;
public boolean subscriptionNotifications;
@JsonProperty("new_offers")
public boolean newOffersNotify;
@JsonProperty("order_status_changed")
public boolean orderStatusChangedNotify;
@JsonProperty("hot_offers")
public boolean hotOffersNotify;
}
Request that I need to parse into POJO.
{
"customer_id": 84,
"token_api": "ef5d7d2cd5dfa27a",
"token_expire_unix": "1435113663",
"preferences": {
"new_offers": "1",
"order_status_changed": "1",
"hot_offers": "1"
}
}
Please help, how can I do this using Jackson. I would be very grateful for any help. Thanks in advance.
1 Answer 1
The main problem lies inside of UserPreferences. Right now your code is attempting to deserialize "1" as a boolean. Java will not do this translation for you, so you will need to create a custom deserializer and apply it to the fields with numeric booleans.
Create a Custom Deserializer
A deserializer allows you to specify a class and apply custom operations to how it is created from JSON:
public class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
int intValue = p.getValueAsInt();
switch (intValue) {
case 0:
return Boolean.TRUE;
case 1:
return Boolean.FALSE;
default:
// throw exception or fail silently
}
return null; // can throw an exception if failure is desired
}
}
Apply Custom Deserialization to Fields
Since you probably don't want to register this on your ObjectMapper and apply it to all deserialization, you can use the @JsonDeserialize annotation. Your UserPreferences class will end up looking something like this:
public class UserPreferences {
public boolean offersNotifications;
public boolean statusChangedNotifications;
public boolean subscriptionNotifications;
@JsonProperty("new_offers")
@JsonDeserialize(using = NumericBooleanDeserializer.class)
public boolean newOffersNotify;
@JsonProperty("order_status_changed")
@JsonDeserialize(using = NumericBooleanDeserializer.class)
public boolean orderStatusChangedNotify;
@JsonProperty("hot_offers")
@JsonDeserialize(using = NumericBooleanDeserializer.class)
public boolean hotOffersNotify;
}
Make Sure @JsonProperty Matches JSON Keys
Since your JSON has "preferences" and the name of your Java property is userPreferences you will need to slap a @JsonProperty("preferences") on the property inside of User