FasterXml Jackson正确序列化,但不会在ZonedDateTime上调用反序列化

时间:2015-02-20 12:12:59

标签: java json json-deserialization mapper

我正在开发一个需要FasterXML和ZonedDateTime的项目。必须不使用using=Deserializer.class之类的注释,因为我们希望在所有项目中保持相同的日期格式。

话虽如此,我来这里寻求帮助,因为我无法弄清楚为什么我的Deserializer是实例化的,但它的方法deserialize()不是调用...

这是我的配置:

序列化器:

public class ZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime> {

    /**
     * The date time formatter to use
     */
    DateTimeFormatter dtf;

    /**
     * Instanciate a new serializer
     *
     * @param dtf The datetime formatter
     */
    public ZonedDateTimeSerializer(DateTimeFormatter dtf) {
        System.out.println("ZonedDateTimeSerializer()");
        this.dtf = dtf;
    }


    @Override
    public void serialize(ZonedDateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        System.out.println("ZonedDateTimeSerializer::serialize()");
        if (null != dateTime) {
            jsonGenerator.writeString(dateTime.format(dtf));
        }
    }
}

反序列化器:

public class ZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {

    /**
     * The date time formatter to use
     */
    DateTimeFormatter dtf;

    /**
     * Instanciate a new deserializer
     *
     * @param dtf The datetime formatter
     */
    public ZonedDateTimeDeserializer(DateTimeFormatter dtf) {
        Preconditions.checkNotNull(dtf, "Date time formatter is null");
        System.out.println("ZonedDateTimeDeserializer()");
        this.dtf = dtf;
    }

    @Override
    public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        System.out.println("ZonedDateTimeDeserializer::deserialize()");
        return ZonedDateTime.parse(jsonParser.getText(), dtf);
    }
}

这两个在mapper提供者中添加到mapper中:

@Provider
public class JacksonConfigurator implements ContextResolver<ObjectMapper> {

    private ObjectMapper mapper = new ObjectMapper();

    /**
     * Constructor
     */
    public JacksonConfigurator() {

        System.out.println("new ObjectMapperResolver()");
        DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

        SimpleModule xxxModule = new SimpleModule("XXXX", new Version(2, 0, 0, null))
                .addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer(sdf))
                .addDeserializer(ZonedDateTime.class, new ZonedDateTimeDeserializer(sdf));

        mapper.registerModule(xxxModule);
    }

    @Override
    public ObjectMapper getContext(Class<?> arg0) {
        return mapper;
    }
}

在这里注册玻璃鱼球衣ResourceConfig;

@ApplicationPath("api")
public class ApplicationRessourceConfig extends ResourceConfig {

    /**
     * Define application config
     */
    public ApplicationRessourceConfig() {

        // File to parse
        packages(true, "com.xxx.xxx");

        // CDI to Jersey
        register(new WebServiceBinder());

        // Jackson config
        register(new JacksonConfigurator());

        // Role
        register(RolesAllowedDynamicFeature.class);
    }
}

在测试没问题之前,我无法在生产或开发中测试它。所以我做了如下测试:

public class xxxTest extends JerseyTest {
    ...
    @Override
    protected Application configure() {
        ...
        ResourceConfig config = new ResourceConfig(...);

        config.register(new JacksonConfigurator());

        return config;
    }

    @Test
    public void xxx() {
        ...
        response.bufferEntity();
        response.readEntity(EntityWithZonedDateTime.class);
        ...
    } 
}

当我在每个ZonedDateTime属性上使用注释@JsonDeserializer时,它工作得很好但是现在,Serializer构造函数被记录,serialize()也被记录,事件为Deserializer记录构造函数,但不记录deserialize()方法。

相反,我有:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.ZonedDateTime] from String value ('2012-06-30T12:30:40.000+0000'); no single-String constructor/factory method
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@3af4e0bf; line: 1, column: 46] (through reference chain: com.xxx.xxx.resources.utils.Xxxx["beginDate"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:843)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:277)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:284)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1150)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:153)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:144)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:523)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101)
at com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap.findDeserializeAndSet(BeanPropertyMap.java:285)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:248)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:136)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1408)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:858)
at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777)

下午2点,我将在48小时内完成。无法知道为什么映射器不会尝试使用反序列化器进行desiarilize并且它会回退到字符串上。猜猜是什么......更快的xml wiki已经失败了...任何线索都是受欢迎的。

---编辑---

有关信息,请求中发送的实体如下所示:

@XmlRootElement
public class XxxOutput {

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public static class XxxJson {

        /* ---------- Properties ---------- */
        public BigInteger id;

        public String name;

        public String definition;

        public ZonedDateTime beginDate;

        public ZonedDateTime endDate;

        public ZonedDateTime creationDate;

        public ZonedDateTime lastUpdate;

        public Map<String, BigInteger> relateds;

        /* ---------- Constructor ---------- */
        public XxxJson() {}

        public XxxJson(... all args ...) {
            this.id = id;
            ...
            this.relateds = relateds;
        }
        /* ---------- Useful methods ---------- */
        public XxxJson addRelated(final Xxx related) {
            ...
            // add the Xxx.id to the list
            ...
        }

        @Override
        public String toString() {
            return id.toString();
        }
    }
 }

0 个答案:

没有答案