1
votes

I'm currently implementing parsing of JSON to POJO.

My Model class looks like this:

public class InvoiceModel {
    @JsonDeserialize(using=MeteorDateDeserializer.class)
    Date date;
    String userId;
    String customerName;
    ArrayList<PaymentModel> payments;
    [...getters, setters...]
}

a JSON string could look like this:

{
  "date": {
    "$date": 1453812396858
  },
  "userId": "igxL4tNwR58xuuJbE",
  "customerName": "S04",
  "payments": [
    {
      "value": 653.5,
      "paymentMethod": "Cash",
      "userId": "igxL4tNwR58xuuJbE",
      "date": {
        "$date": 1453812399033
      }
    }
  ]
}

though the payments field may be omitted. Anywho, doesn't really matter too much for the question. You see, the format for parsing the date is somewhat "odd" as in it is encapsulated in the "$date" property of the "date" object. This is however not in my control.

To get around this problem I wrote a custom JSON Deserializer to use for this date property. It looks like this:

public class MeteorDateDeserializer extends org.codehaus.jackson.map.JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        // parse the "$date" field found by traversing the given tokens of jsonParser 
        while(!jsonParser.isClosed()){
            JsonToken jsonToken = jsonParser.nextToken();
            if(JsonToken.FIELD_NAME.equals(jsonToken)){
                String fieldName = jsonParser.getCurrentName();
                jsonToken = jsonParser.nextToken();
                if("$date".equals(fieldName)){
                    long timeStamp = jsonParser.getLongValue();
                    return new java.util.Date(timeStamp);
                }
            }
        }

        return null;
    }
}

The exact problem is the following:

The returned InvoiceModel POJO has every attribute apart from "date" set to null, whereas the date is parsed fine. I have narrowed down the problem to the custom Date Deserializer by not deserializing the date at all (just deserializing the 2 string values and the payments array, which works fine).

My thesis is that the annotation conveys to Jackson that the custom deserializer is to be used for the whole class instead of being used just for the date field. According to the doc this should not be the case:

Annotation use for configuring deserialization aspects, by attaching to "setter" methods or fields, or to

The call to the serialization is nothing special. It's just a standard ObjectMapper call.

 InvoiceModel invoice = mapper.readValue(s2, InvoiceModel.class);

where s2 is the JSON string.

My version of Jackson is 1.9.7

I think I found the answer to a rather similar problem. The source of the problem may be the inner state of the JsonParser after your Deserializer run.blafasel