Dropwizard如何知道如何序列化Joda DateTime对象,以及如何修改它?

时间:2018-01-18 00:35:59

标签: java jodatime dropwizard

我正在寻找使用DropWizard的REST API。 DropWizard以某种方式神奇地知道如何将joda DateTime对象序列化为一个格式如下的字符串:

YYYY-MM-DD HH:MM:SS

但是如果我编写一个使用ObjectMapper来序列化joda DateTime对象的测试,我会得到类似的东西:

{"month_of_year":1,"hour_of_day":0,"minute_of_hour":15,"second_of_minute":3,"millis_of_second":0,"week_of_weekyear":3,"weekyear":2018,"year_of_era":2018,"year_of_century":18,"century_of_era":20,"millis_of_day":903000,"second_of_day":903,"minute_of_day":15,"day_of_year":18,"day_of_week":4,"day_of_month":18,"year":2018,"era":1,"millis":1516259703000,"chronology":{"zone":{"uncached_zone":{"cachable":true,"fixed":false,"id":"America/Denver"},"fixed":false,"id":"America/Denver"}},"zone":{"uncached_zone":{"cachable":true,"fixed":false,"id":"America/Denver"},"fixed":false,"id":"America/Denver"},"after_now":true,"before_now":false,"equal_now":false}

DropWizard如何知道如何序列化?

我序列化的字段注释如下:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-dd HH:mm:ss")
DateTime myDate;

我知道我在那里提供了一个格式字符串,但我想了解为什么ObjectMapper(在我的测试中)不尊重它,而DropWizard则如此。 (注释是杰克逊的注释,而不是DropWizard注释,因此让我感到困惑的是ObjectMapper.writeValue()不会尊重它。)

在查看@JsonFormat注释的来源时,我看到:

/**
 * Datatype-specific additional piece of configuration that may be used
 * to further refine formatting aspects. This may, for example, determine
 * low-level format String used for {@link java.util.Date} serialization;
 * however, exact use is determined by specific <code>JsonSerializer</code>
 */
public String pattern() default "";

这让我相信Jackson实际上并没有提供识别此JsonSerializer属性的pattern,同时让我相信DropWizard确实有这样的JsonSerializer }。如何配置/修改/覆盖DropWizard显然正在使用的JsonSerializer

1 个答案:

答案 0 :(得分:2)

您的测试未使用正确的ObjectMapper。 DW在其引导程序中将为您配置ObjectMapper合理的默认值(这是DW的全部内容 - 一切都有点合理且预先配置)。

因此,在您的情况下,您的测试需要使用Jackson.newObjectMapper()。试试这个:

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

    ObjectMapper myMapper=  new ObjectMapper();
    ObjectMapper dwMapper = Jackson.newObjectMapper();
    System.out.println(myMapper.writeValueAsString(new X()));
    System.out.println(dwMapper.writeValueAsString(new X()));
}

public static class X { 
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-dd HH:mm:ss")
    DateTime now = DateTime.now();
}

将打印:

{"now":{"era":1,"dayOfYear":18,"dayOfWeek":4,"dayOfMonth":18,"year":2018,"weekOfWeekyear":3,"millisOfDay":37615193,"monthOfYear":1,"hourOfDay":10,"minuteOfHour":26,"secondOfMinute":55,"millisOfSecond":193,"weekyear":2018,"yearOfEra":2018,"yearOfCentury":18,"centuryOfEra":20,"secondOfDay":37615,"minuteOfDay":626,"zone":{"fixed":false,"uncachedZone":{"cachable":true,"fixed":false,"id":"Europe/London"},"id":"Europe/London"},"millis":1516271215193,"chronology":{"zone":{"fixed":false,"uncachedZone":{"cachable":true,"fixed":false,"id":"Europe/London"},"id":"Europe/London"}},"afterNow":false,"beforeNow":true,"equalNow":false}}
{"now":"2018-01-18 10:26:55"}

为了完整起见,这些是为您注册的模块:

private static ObjectMapper configure(ObjectMapper mapper) {
        mapper.registerModule(new GuavaModule());
        mapper.registerModule(new LogbackModule());
        mapper.registerModule(new GuavaExtrasModule());
        mapper.registerModule(new JodaModule());
        mapper.registerModule(new AfterburnerModule());
        mapper.registerModule(new FuzzyEnumModule());
        mapper.registerModules(new Jdk8Module());
        mapper.registerModules(new JavaTimeModule());
        mapper.setPropertyNamingStrategy(new AnnotationSensitivePropertyNamingStrategy());
        mapper.setSubtypeResolver(new DiscoverableSubtypeResolver());

        return mapper;
    }

这些都可以在引导程序中覆盖。

请注意,我可能使用较旧版本的DW,因此最新版本可能略有不同。

阿图尔