我有以下類:Spring + Jackson + joda time:如何指定序列化/反序列化格式?
public static class ARestRequestParam
{
String name;
LocalDate date; // joda type
}
而且我希望它從由傑克遜處理以下JSON反序列化。
{名:「ABC」,日期:「20131217」}
其實,我想反序列化與「年月日」的格式,任何類中的任何LOCALDATE的領域,而不用複製格式字符串,不添加任何setter方法,沒有任何XML配置。 (也就是說,註釋和Java代碼是最好的) 怎麼做?
另外,我也想知道序列化部分。即LocalDate - >「yyyyMMdd」。
我見過如下:
- 傑克遜 - 數據類型 - 喬達(https://github.com/FasterXML/jackson-datatype-joda)
- 自定義序列(公共類JodaDateTimeJsonSerializer擴展JsonSerializer {...} - Spring @ResponseBody Jackson JsonSerializer with JodaTime)
- @JsonCreator
- @DateTimeFormat
但我不知道哪個是appl可用的,並且是最新的。
順便說一句,我使用Spring Boot。
UPDATE
好吧,我已經成功地寫反序列化部分的工作代碼。 它如下:
@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。 (雖然我已經複製了它的代碼)
這個代碼還可以嗎?
這是最新的解決方案嗎?
還有其他更簡單的方法嗎?
任何建議將不勝感激。
UPDATE
繼戴夫Syer的建議,我修改了源上方如下:
刪除2種方法:configureMessageConverters(),jacksonConverter()
添加以下的方法進WebMvcConfiguration類:
@Bean
public Module apiJodaModule()
{
return new ApiJodaModule();
}
但現在它不起作用。看起來apiJodaModule()被忽略。
我該如何使它工作?
(看來我不應該有@EnableWebMvc使用該功能的類。)
我使用的版本是org.springframework.boot:彈簧引導起動網:0.5.0.M6 。
UPDATE
最終工作的版本如下:
戴維Syer提到的,這隻會在BUILD-SNAPSHOT工作(在其他配置我以前在有@EnableWebMvc類已完成)版本,至少現在。
@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");
}
}
謝謝。實際上,我必須將addResourceHandlers()添加到WebMvcConfiguration類才能提供靜態文件(因爲默認設置已消失)。但是因爲我重寫了addInterceptors()來添加URL攔截器,所以我不得不創建自己的具有EnableWebMvc的類。 – zeodtr
另請查看我的更新並給我一些建議。 – zeodtr
爲了添加攔截器,您不需要'@ EnableWebMvc',只需添加類型爲「WebMvcConfigurerAdapter」(標準Spring MVC功能)的'@ Bean'。閱讀答案:「使用快照」。這應該把你排除在外。 –