Jackson Custom Deserializer breaks default ones

旧巷老猫 提交于 2019-12-24 13:48:58

问题


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

来源:https://stackoverflow.com/questions/35525471/jackson-custom-deserializer-breaks-default-ones

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!