【问题标题】:How to dynamically customise deserialiser for date format?如何动态自定义日期格式的反序列化器?
【发布时间】:2019-02-24 18:23:26
【问题描述】:

我正在开发自定义 JSON 反序列化器并拥有以下课程

public class yyyy_MM_dd_DateDeserializer extends StdDeserializer <LocalDate> {

 public yyyy_MM_dd_DateDeserializer() {
  this(null);
 }

 public yyyy_MM_dd_DateDeserializer(Class t) {
  super(t);
 }

 @Override
 public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
  String dateString = jsonParser.getText();
  LocalDate localDate = null;
  try {
   localDate = LocalDate.parse(dateString, "yyyy-MM-dd");
  } catch (DateTimeParseException ex) {
   throw new RuntimeException("Unparsable date: " + dateString);
  }
  return localDate;
 }
}

在我的请求类中

@Valid
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
private LocalDate endDate;

它工作正常,但我想知道我是否可以动态传递日期格式。而不是在yyyy_MM_dd_DateDeserializer 中进行硬编码。 我想从我的请求类中传递日期格式,以便我的反序列化器更通用,任何人都可以通过发送所需的格式来使用它。

【问题讨论】:

    标签: java json json-deserialization localdate


    【解决方案1】:

    我认为你工作太努力了,没有得到你想要的。有一种更简单的方法,无需编写自己的反序列化器。看this question。本质上它看起来像

    @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
    @JsonProperty("created_at") 
    ZonedDateTime created_at;
    

    你只需戴上你自己的面具。另外,我曾经有一个任务是解析未知格式的日期,本质上我需要解析任何有效的日期。这是一篇描述如何实现它的想法的文章:Java 8 java.time package: parsing any string to date。您可能会发现它很有用

    【讨论】:

    • 谢谢,在我的情况下,格式是“yyyy-MM-dd”,如果我发送“12-31-2019”,它将转换为有效日期。但我需要一个日期格式错误的错误。于是创建了 CustomDateDeserializer
    【解决方案2】:

    在使用活页夹库时不会(绑定的关键在于它不是动态的。)。

    但你可以在使用简单的解析库时,例如 org.json

    【讨论】:

      【解决方案3】:

      当您使用java.time.* 类和Jackson 时,最好从注册来自jackson-datatype-jsr310 模块的JavaTimeModule 开始。我们可以扩展它并使用提供的模式注册序列化器,如下例所示:

      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
      import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
      
      import java.time.LocalDate;
      import java.time.format.DateTimeFormatter;
      
      public class JsonApp {
      
          public static void main(String[] args) throws Exception {
              ObjectMapper mapperIso = createObjectMapper("yyyy-MM-dd");
              ObjectMapper mapperCustom0 = createObjectMapper("yyyy/MM/dd");
              ObjectMapper mapperCustom1 = createObjectMapper("MM-dd-yyyy");
      
              System.out.println(mapperIso.writeValueAsString(new Time()));
              System.out.println(mapperCustom0.writeValueAsString(new Time()));
              System.out.println(mapperCustom1.writeValueAsString(new Time()));
          }
      
          private static ObjectMapper createObjectMapper(String pattern) {
              JavaTimeModule javaTimeModule = new JavaTimeModule();
              javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(pattern)));
      
              ObjectMapper mapper = new ObjectMapper();
              mapper.registerModule(javaTimeModule);
      
              return mapper;
          }
      }
      
      class Time {
      
          private LocalDate now = LocalDate.now();
      
          public LocalDate getNow() {
              return now;
          }
      
          public void setNow(LocalDate now) {
              this.now = now;
          }
      
          @Override
          public String toString() {
              return "Time{" +
                      "now=" + now +
                      '}';
          }
      }
      

      Aboce 代码打印:

      {"now":"2019-02-24"}
      {"now":"2019/02/24"}
      {"now":"02-24-2019"}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-18
        • 1970-01-01
        • 2013-10-26
        • 1970-01-01
        • 2015-01-30
        • 2020-02-12
        • 2016-11-30
        • 1970-01-01
        相关资源
        最近更新 更多