我有以下课程:
public static class ARestRequestParam { String name; LocalDate date; // joda type }
我希望将其从以下由jackson处理的JSON反序列化。
{名称:“ abc”,日期:“ 20131217”}
实际上,我想反序列化“ yyyyMMdd”格式的任何类中的任何LocalDate字段,而无需复制格式字符串,不添加任何setter方法,不进行任何XML配置。(也就是说,最好使用批注和Java代码)如何完成?
另外,我也想知道序列化部分。即LocalDate->“ yyyyMMdd”。
我看过以下内容:
但是我不知道哪个适用,哪个是最新的。
顺便说一句,我使用Spring Boot。
更新
好的,我已经设法为反序列化部分编写了工作代码。如下:
@Configuration @EnableWebMvc public class WebMvcConfiguration extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters( List<HttpMessageConverter<?>> 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<LocalDate> { 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。(尽管我已经复制了部分代码)
这段代码可以吗? 这是最新的解决方案吗? 还有其他更简单的方法吗? 任何建议将不胜感激。
根据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。
最终的工作版本如下:(与我之前在具有@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<LocalDate> { 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"); } }
您的代码还可以,但是如果您@EnableWebMvc在Spring Boot应用程序中使用代码,则会关闭框架中的默认设置,因此也许应该避免这种情况。此外,您现在在MVC处理程序适配器中只有 一个 HttpMessageConverter。如果您使用Spring Boot的快照,则应该能够简单地定义a @Bean类型Module,其他所有内容都是自动的,因此我建议您这样做。
@EnableWebMvc
HttpMessageConverter
@Bean
Module