首页 > 解决方案 > Object.class 上的 Jackson UntypedObjectDeserializer 仅取消实现日期字符串而不是其他字符串

问题描述

我面临一个非常奇怪的问题。我有以下实现。

    objectMapper = new ObjectMapper();
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

    SimpleModule module = new SimpleModule("DateConverter");

    // register a new deserializer extending and replacing UntypedObjectDeserializer
    module.addDeserializer(Object.class, new CustomObjectDeserializer());
    objectMapper.registerModule(module);
    public class CustomObjectDeserializer extends UntypedObjectDeserializer
    {
        private static final String JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
        private static final String UTC_STRING = "UTC";

        public CustomObjectDeserializer() {
            super(null, null);
        }

        @Override
        public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException
        {
            if (p.currentTokenId() == JsonTokenId.ID_STRING)
            {
                final DateFormat format = new SimpleDateFormat(JSON_DATE_FORMAT);
                // Incoming dates need to be converted into UTC timezone.
                format.setTimeZone(TimeZone.getTimeZone(UTC_STRING));
                try
                {
                    String value = p.getText();
                    System.out.println("Value : " + value);
                    return format.parse(value);
                }
                catch (Exception e) {
                    return super.deserialize(p, ctxt);
                }
            }
            else {
                return super.deserialize(p, ctxt);
            }
        }
    }

对于以下 JSON 请求:

{
      "field": "StartTime",
      "fieldType": null,
      "operator": "<=",
      "value": "2013-05-23T18:29:59.999Z",
      "connector": "AND",
      "parameterName": null
}

输出:

Value : 2013-05-23T12:59:59.999+0000

为什么只有日期类型的字符串字段在这里被反序列化,而不是其他字符串。此外,为了交叉检查,我创建了另一个反序列化器作为 StringDeserealizer,它在 String.class 而不是 Object.class 上工作,并且包括日期字符串在内的所有字符串都被反序列化了。

它是如此令人困惑。为什么 ObjectDeserealizer 不考虑字符串?

标签: javaspring-bootjacksonobjectmapper

解决方案


我认为最好的事情是你可以编写一个自定义的反序列化器Date。像这样的东西,

public class CustomDateDeserializer extends JsonDeserializer<Date> {
    
    private static final String JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
    private static final String UTC_STRING = "UTC";

    @Override
    public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
        String dateString = jsonparser.getText();
        final SimpleDateFormat format = new SimpleDateFormat(JSON_DATE_FORMAT);
        format.setTimeZone(TimeZone.getTimeZone(UTC_STRING));

        try { return format.parse(dateString); }
        catch (Exception e) { return null; }
    }
}
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Date.class, new CustomDateDeserializer());
mapper.registerModule(module);

推荐阅读