Sergio Sanchez Sergio Sanchez - 2 months ago 21
JSON Question

jackson custom deserializer not called

I have the following endpoint in retrofit:

@GET("user/detail")
Observable<JacksonResponse<User>> getUserDetail();


This endpoint returns the following result:

{
"code":1012,
"status":"sucess",
"message":"Datos Del Usuario",
"time":"28-10-2015 10:42:04",
"data":{
"id_hash":977417640,
"user_name":"Daniel",
"user_surname":"Hdz Iglesias",
"birthdate":"1990-02-07",
"height":190,
"weight":80,
"sex":2,
"photo_path":" https:\/\/graph.facebook.com
\/422\/picture?width=100&height=100"
}
}


Here is the definition of the class:

public class JacksonResponse<T> {

private Integer code;
private String status;
private String message;
private String time;
@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;

public JacksonResponse(){}

@JsonCreator
public JacksonResponse(
@JsonProperty("code") Integer code,
@JsonProperty("status") String status,
@JsonProperty("message") String message,
@JsonProperty("time") String time,
@JsonProperty("data") T data) {
this.code = code;
this.status = status;
this.message = message;
this.time = time;
this.data = data;
}

public Integer getCode() {
return code;
}

public void setCode(Integer code) {
this.code = code;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public String getTime() {
return time;
}

public void setTime(String time) {
this.time = time;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

}


I want the content "data" is mapped to the user class, whose extract show here:

@JsonIgnoreProperties(ignoreUnknown = true)
@ModelContainer
@Table(database = AppDatabase.class)
public class User extends BaseModel {

@PrimaryKey(autoincrement = true)
private Long id;
@Column
private Long idFacebook;
@Column
@JsonProperty("user_name")
private String name;
@Column
@JsonProperty("user_surname")
private String surname;
@Column
private Date birthday;
@Column
@JsonProperty("height")
private Double height;
@Column
@JsonProperty("weight")
private Double weight;
@Column
private String tokenFacebook;
@Column
@JsonProperty("sex")
private Integer sex;
@Column
private String email;
@Column
private String token;
@Column
private Date lastActivity;
@Column
@JsonProperty("id_hash")
private Long idHash;
@Column
@JsonProperty("photo_path")
private String photoPath;


To birthdate, I have defined a custom deserializer, whose code show here:

public class BirthdayDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext deserializationcontext) throws IOException {

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = jsonparser.getText();
try {
return format.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}

}


I am using this as follows (at User class):

@JsonProperty("birthday")
@JsonDeserialize(using = BirthdayDeserializer.class)
public void setBirthday(Date birthday) {
this.birthday = birthday;
}


but this is never called.

Any idea what 's going on?

Answer

You Pojo and JSON does not map. You need to have a Data.java which should have properties as given in the JSON. you classes should be as below based on the json given above.

User.java

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {

    @JsonProperty("code")
    public Integer code;
    @JsonProperty("status")
    public String status;
    @JsonProperty("message")
    public String message;
    @JsonProperty("time")
    public String time;
    @JsonProperty("data")
    public Data data;

}

Data.java

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Data {

    @JsonProperty("id_hash")
    public Integer idHash;
    @JsonProperty("user_name")
    public String userName;
    @JsonProperty("user_surname")
    public String userSurname;
    @JsonProperty("birthdate")
    @JsonDeserialize(using = BirthdayDeserializer.class)
    public Date birthdate;
    @JsonProperty("height")
    public Integer height;
    @JsonProperty("weight")
    public Integer weight;
    @JsonProperty("sex")
    public Integer sex;
    @JsonProperty("photo_path")
    public String photoPath;

}

Main.java to test it.

public class Main {

    public static void main(String[] args) throws IOException {

        String json = "{\n" +
                "    \"code\": 1012,\n" +
                "    \"status\": \"sucess\",\n" +
                "    \"message\": \"Datos Del Usuario\",\n" +
                "    \"time\": \"28-10-2015 10:42:04\",\n" +
                "    \"data\": {\n" +
                "        \"id_hash\": 977417640,\n" +
                "        \"user_name\": \"Daniel\",\n" +
                "        \"user_surname\": \"Hdz Iglesias\",\n" +
                "        \"birthdate\": \"1990-02-07\",\n" +
                "        \"height\": 190,\n" +
                "        \"weight\": 80,\n" +
                "        \"sex\": 2\n" +
                "    }\n" +
                "}";
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Date.class, new BirthdayDeserializer());
        mapper.registerModule(module);
        User readValue = mapper.readValue(json, User.class);
    }
}