gpt4 book ai didi

spring-mvc - Spring + Jackson + joda time : how to specify the serialization/deserialization format?

转载 作者:行者123 更新时间:2023-12-04 01:23:16 28 4
gpt4 key购买 nike

我有以下类(class):

public static class ARestRequestParam
{
String name;
LocalDate date; // joda type
}

我希望它从 jackson 处理的以下 JSON 中反序列化。

{名称:“abc”,日期:“20131217”}

实际上,我想反序列化任何具有“yyyyMMdd”格式的类中的任何 LocalDate 字段,而不复制格式字符串,不添加任何 setter 方法,不进行任何 XML 配置。 (即注解和Java代码更可取)
如何做呢?

另外,我也想知道序列化部分。也就是说,LocalDate -> "yyyyMMdd"。

我看过以下内容:
  • jackson 数据类型乔达(https://github.com/FasterXML/jackson-datatype-joda)
  • 自定义序列化程序(公共(public)类 JodaDateTimeJsonSerializer 扩展 JsonSerializer { ... } - Spring @ResponseBody Jackson JsonSerializer with JodaTime )
  • @JsonCreator
  • @日期时间格式

  • 但我不知道哪个是适用的,哪个是最新的。

    顺便说一句,我使用 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 应用程序中,您关闭了框架中的默认设置,所以也许您应该避免这种情况。此外,您现在只有一个 HttpMessageConverter在您的 MVC 处理程序适配器中。如果你使用 Spring Boot 的快照,你应该能够简单地定义一个 @Bean类型 Module其他一切都是自动的,所以我建议这样做。

    关于spring-mvc - Spring + Jackson + joda time : how to specify the serialization/deserialization format?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20648706/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com