Dropwizard 如何知道如何序列化 Joda DateTime 对象,我该如何修改它?
How does Dropwizard know how to serialize Joda DateTime objects, and how can I modify it?
我正在查看使用 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 遵守。 (注释是 Jackson 注释,而不是 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 实际上并没有提供识别这个 pattern
属性的 JsonSerializer
,同时让我相信 DropWizard 确实有这样一个 JsonSerializer
。我怎样才能 configure/modify/override DropWizard 显然正在使用的 JsonSerializer
?
您的测试没有使用正确的ObjectMapper
。 DW 在其 bootstrap 中将为您配置 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;
}
这些在bootstrap中都是可以覆盖的。
请注意,我可能使用的是旧版本的 DW,因此最新版本可能略有不同。
阿图尔
我正在查看使用 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 遵守。 (注释是 Jackson 注释,而不是 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 实际上并没有提供识别这个 pattern
属性的 JsonSerializer
,同时让我相信 DropWizard 确实有这样一个 JsonSerializer
。我怎样才能 configure/modify/override DropWizard 显然正在使用的 JsonSerializer
?
您的测试没有使用正确的ObjectMapper
。 DW 在其 bootstrap 中将为您配置 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;
}
这些在bootstrap中都是可以覆盖的。
请注意,我可能使用的是旧版本的 DW,因此最新版本可能略有不同。
阿图尔