我正在寻找使用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
?
答案 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,因此最新版本可能略有不同。
阿图尔