Как динамически настроить десериализатор для формата даты? - PullRequest
0 голосов
/ 24 февраля 2019

Я работаю над нестандартным 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.Я хочу передать формат даты из моего класса запросов, чтобы мой десериализатор был более универсальным, и любой желающий мог его использовать, отправив требуемый формат.

Ответы [ 3 ]

0 голосов
/ 24 февраля 2019

Я думаю, вы слишком усердно работаете, чтобы получить то, что вы хотите.Существует более простой способ без написания собственного десериализатора.Посмотрите на этот вопрос .По сути это выглядит как

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

И вы просто надеваете собственную маску.Кроме того, однажды у меня была задача разбора даты в неизвестном формате, по сути, мне нужно было проанализировать любую действительную дату.Вот статья, описывающая идею о том, как ее реализовать: Java 8 пакет java.time: разбор любой строки на сегодняшний день .Вы можете найти это полезным

0 голосов
/ 24 февраля 2019

Когда вы работаете с java.time.* классами и Jackson, лучше начать с регистрации JavaTimeModule, которая поступает из модуля jackson-datatype-jsr310 .Мы можем расширить его и зарегистрировать сериализатор с предоставленным шаблоном, как показано в следующем примере:

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"}
0 голосов
/ 24 февраля 2019

Не при использовании библиотеки подшивки (сама точка привязки заключается в том, что она не динамическая.)

...