I wanted to serialize list with different objects of the class Person
with a firstname
, lastname
and a birthday
. After looking at different questions in the forum here I found out that I need to register the jsr.310.JavaTimeModule
to serialize the LocalDate birthday
. I know there are many entries on this site regarding this topic but most of them say that registering the module is enough to handle the LocalDate
.
This is my writer class:
public void write(){
ArrayList<Person> personList = new ArrayList<>();
Person p1 = new Person("Peter", "Griffin", LocalDate.of(1988,6,5));
Person p2 = new Person("Lois", "Griffin", LocalDate.of(1997,9,22));
personList.add(p1);
personList.add(p2);
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());
try {
writer.writeValue(new File(System.getProperty("user.dir")+"/File/Personen.json"), personList);
} catch (IOException e) {
e.printStackTrace();
}
}
and my Reader class is:
public void read(){
ObjectMapper mapper = new ObjectMapper();
try {
ArrayList<Person> liste = mapper.readValue(new FileInputStream("File/Personen.json"),
mapper.getTypeFactory().constructCollectionType(ArrayList.class, Person.class));
System.out.println(liste.get(0).getFirstname());
} catch (IOException e) {
e.printStackTrace();
}
}
After reading the file I get a
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of java.time.LocalDate (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('1988-06-05')
at [Source: (FileInputStream); line: 4, column: 18] (through reference chain: java.util.ArrayList[0]->Person["birthday"])
I thought I don't need to do anything more than registering the TimeModule
. Do I need to register a module for the reader as well? Or is there another problem with my code?
You correctly registered the JavaTimeModule
with the
ObjectMapper
in your write()
method.
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
But you forgot to register it with the ObjectMapper
in your read()
method.
ObjectMapper mapper = new ObjectMapper();
To fix it, just add the missing .registerModule(new JavaTimeModule())
there.
Or better yet:
Remove the local ObjectMapper
definitions from your write
and read
methods.
Instead, add it as a member variable to your class, so that you can use
the same ObjectMapper
instance in both methods.
private ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());