Frühjahr + Jackson + joda time: so legen Sie die Serialisierung/Deserialisierung-format?
Habe ich die folgende Klasse:
public static class ARestRequestParam
{
String name;
LocalDate date; //joda type
}
Und ich will es deserialisiert werden aus der folgenden JSON, die verarbeitet wird, durch jackson.
{ name:"abc", Datum:"20131217" }
Eigentlich will ich zu Deserialisieren alle LocalDate Feld in einer Klasse mit "JJJJMMTT" - format, ohne duplizieren der format-string ohne jede setter-Methode, ohne XML-Konfiguration. (Das ist, Beschriftungs-und Java-code ist besser)
Wie kann es getan werden?
Auch, ich auch wollen zu wissen die Serialisierung Teil. das ist, LocalDate -> "JJJJMMTT".
Gesehen hab ich Folgendes:
- jackson-datatype-joda (https://github.com/FasterXML/jackson-datatype-joda)
- benutzerdefinierte serializer (public class JodaDateTimeJsonSerializer erstreckt JsonSerializer { ... } - Spring @ResponseBody Jackson JsonSerializer mit JodaTime)
- @JsonCreator
- @DateTimeFormat
Aber ich weiß nicht, was anwendbar ist, und die meisten up-to-date.
BTW, ich benutze Spring Boot.
UPDATE
Ok, ich habe es geschafft, zu schreiben funktionierenden code für die Deserialisierung Teil.
Es ist wie folgt:
@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");
}
}
}
Ich hatte zur Umsetzung der deserializer mich, da die datetime-format für die deserializer, die im jackson-datatype-joda nicht verändert werden kann. So, da habe ich umgesetzt deserializer mich, jackson-datatype-joda ist nicht erforderlich. (obwohl ich kopiert habe Teile des Codes)
Ist dieser code Ok?
Ist dieser up-to-date-Lösung?
Gibt es einen anderen einfacheren Weg?
Jeder Vorschlag wäre sehr dankbar.
UPDATE
Folgenden Dave Syer Vorschlag, modifizierte ich die Quelle oben wie folgt:
Entfernt 2 Methoden: configureMessageConverters(), jacksonConverter()
Hinzugefügt folgende Methode in WebMvcConfiguration-Klasse:
@Bean
public Module apiJodaModule()
{
return new ApiJodaModule();
}
Aber jetzt funktioniert es nicht. Es scheint apiJodaModule() wird ignoriert.
Wie kann ich machen, damit es funktioniert?
(Es scheint, dass ich nicht haben sollte eine Klasse, die hat @EnableWebMvc, diese Funktion zu verwenden.)
Die version, die ich benutze, ist org.springframework.boot:spring-boot-starter-web:0.5.0.M6.
UPDATE
Letzte funktionierende version ist wie folgt: (mit anderen Konfigurationen, die ich bisher gemacht haben in der Klasse, die hatte @EnableWebMvc)
Wie Dave Syer erwähnt, funktioniert das nur auf BUILD-SNAPSHOT-version, zumindest für jetzt.
@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");
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dein code ist OK, aber wenn Sie
@EnableWebMvc
in eine Spring-Boot-Anwendung, die Sie schalten Sie die Standard-Einstellungen in den Rahmen, so sollten Sie vielleicht vermeiden, dass. Auch Sie haben jetzt nur eineHttpMessageConverter
im MVC handler-adapter. Wenn Sie einen snapshot von Spring Boot, Sie sollten in der Lage sein zu definieren einfach eine@Bean
TypModule
und alles andere würde automatisch erfolgen, so würde ich empfehlen, es zu tun auf diese Weise.@EnableWebMvc
um Abfangjäger, fügen Sie einfach eine@Bean
TypWebMvcConfigurerAdapter
(standard-Spring MVC-Funktion). Die Antwort Lesen: "verwenden Sie einen snapshot". Das sollte Sortieren Sie aus.@Bean
TypObjectMapper