1

I am working on custom JSON deserialiser and have the below class

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;
 }
}

and in my request class

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

It works fine but I am wondering if I can pass the date format dynamically. Instead of hardcoding in yyyy_MM_dd_DateDeserializer. I want to pass the date format from my request class so that my deserialiser is more generic any anyone can use it by sending the required format.

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
kkgg
  • 21
  • 3

3 Answers3

1

I think you working too hard to get what you want. There is a simpler way without writing your own deserializer. Look at this question. Essentially it looks like

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

And you just put your own mask. Also, I once had a task of parsing date with unknown format, essentially I needed to parse any valid date. Here is an article describing the idea of how to implement it: Java 8 java.time package: parsing any string to date. You might find it useful

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • 1
    thanks, in my case the format is "yyyy-MM-dd" and if I send "12-31-2019" it is converting to a valid date. But I need a error that date format is wrong. So created CustomDateDeserializer – kkgg Feb 27 '19 at 01:56
0

Not when using a binder library (The very point of binding is that it is not dynamic.).

But you could when using a simple parsing library such as org.json

kumesana
  • 2,495
  • 1
  • 9
  • 10
0

When you are working with java.time.* classes and Jackson is good to start from registering JavaTimeModule which comes from jackson-datatype-jsr310 module. We can extend it and register serialiser with provided pattern like in below example:

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 code prints:

{"now":"2019-02-24"}
{"now":"2019/02/24"}
{"now":"02-24-2019"}
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146