我有以下课程:
public static class ARestRequestParam { String name; LocalDate date; // joda type }
我希望它可以从杰克逊处理的以下JSON中反序列化.
{name:"abc",date:"20131217"}
实际上,我希望使用"yyyyMMdd"格式反序列化任何类中的任何LocalDate字段,而不重复格式字符串,而不添加任何setter方法,不需要任何XML配置.(也就是说,注释和Java代码更可取)如何才能完成?
另外,我也想知道序列化部分.也就是LocalDate - >"yyyyMMdd".
我见过以下情况:
jackson-datatype-joda(https://github.com/FasterXML/jackson-datatype-joda)
自定义序列化器(公共类JodaDateTimeJsonSerializer扩展JsonSerializer {...} - Spring @ResponseBody Jackson JsonSerializer与JodaTime)
@JsonCreator
@DateTimeFormat
但我不知道哪个适用,哪个是最新的.
顺便说一句,我使用Spring Boot.
UPDATE
好的,我已经设法为反序列化部分编写工作代码.它如下:
@Configuration @EnableWebMvc public class WebMvcConfiguration extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters( List> converters) { converters.add(jacksonConverter()); } @Bean public MappingJackson2HttpMessageConverter jacksonConverter() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new ApiJodaModule()); converter.setObjectMapper(mapper); return converter; } @SuppressWarnings("serial") private class ApiJodaModule extends SimpleModule { public ApiJodaModule() { addDeserializer(LocalDate.class, new ApiLocalDateDeserializer()); } } @SuppressWarnings("serial") private static class ApiLocalDateDeserializer extends StdScalarDeserializer { private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyyMMdd"); public ApiLocalDateDeserializer() { super(LocalDate.class); } @Override public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { String s = jp.getText().trim(); if (s.length() == 0) return null; return LocalDate.parse(s, formatter); } throw ctxt.wrongTokenException(jp, JsonToken.NOT_AVAILABLE, "expected JSON Array, String or Number"); } } }
我必须自己实现反序列化器,因为jackson-datatype-joda中的反序列化器的日期时间格式不能改变.因此,由于我自己实现了反序列化器,因此不需要jackson-datatype-joda.(虽然我已复制其代码片段)
这段代码好吗?
这是最新的解决方案吗?
还有其他更简单的方法吗?
任何建议将不胜感激.
UPDATE
根据Dave Syer的建议,我修改了上面的源代码如下:
删除了2个方法:configureMessageConverters(),jacksonConverter()
在WebMvcConfiguration类中添加了以下方法:
@Bean public Module apiJodaModule() { return new ApiJodaModule(); }
但现在它不起作用.似乎apiJodaModule()被忽略了.
我怎样才能使它工作?
(似乎我不应该有一个具有@EnableWebMvc的类来使用该功能.)
我使用的版本是org.springframework.boot:spring-boot-starter-web:0.5.0.M6.
UPDATE
最终的工作版本如下:(我以前在具有@EnableWebMvc的类中完成的其他配置)
正如Dave Syer所提到的,这只适用于BUILD-SNAPSHOT版本,至少目前如此.
@Configuration public class WebMvcConfiguration { @Bean public WebMvcConfigurerAdapter apiWebMvcConfiguration() { return new ApiWebMvcConfiguration(); } @Bean public UserInterceptor userInterceptor() { return new UserInterceptor(); } public class ApiWebMvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor()) .addPathPatterns("/api/user/**"); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("/") .setCachePeriod(0); } } @Bean public Module apiJodaModule() { return new ApiJodaModule(); } @SuppressWarnings("serial") private static class ApiJodaModule extends SimpleModule { public ApiJodaModule() { addDeserializer(LocalDate.class, new ApiLocalDateDeserializer()); } private static final class ApiLocalDateDeserializer extends StdScalarDeserializer{ public ApiLocalDateDeserializer() { super(LocalDate.class); } @Override public LocalDate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { String s = jp.getText().trim(); if (s.length() == 0) return null; return LocalDate.parse(s, localDateFormatter); } throw ctxt.mappingException(LocalDate.class); } } private static DateTimeFormatter localDateFormatter = DateTimeFormat.forPattern("yyyyMMdd"); } }
Dave Syer.. 5
你的代码没问题,但如果你@EnableWebMvc
在Spring Boot应用程序中使用,你可以关闭框架中的默认设置,所以也许你应该避免这样做.此外,您现在只有一个 HttpMessageConverter
在MVC处理程序适配器中.如果你使用Spring Boot的快照,你应该能够简单地定义一个@Bean
类型Module
,其他一切都是自动的,所以我建议这样做.
你的代码没问题,但如果你@EnableWebMvc
在Spring Boot应用程序中使用,你可以关闭框架中的默认设置,所以也许你应该避免这样做.此外,您现在只有一个 HttpMessageConverter
在MVC处理程序适配器中.如果你使用Spring Boot的快照,你应该能够简单地定义一个@Bean
类型Module
,其他一切都是自动的,所以我建议这样做.