1

I never worked with JSON before and wanted to serialize an ArrayList<Person> to a JSON file.

My writer class looks like this:

public class Writer {

public void write(){
    ArrayList<Person> personList = new ArrayList<>();

    Person p1 = new Person("James", "Bond", LocalDate.of(1997,9,22));
    Person p2 = new Person("Santa", "Claus", LocalDate.of(1918,11,6));
    Person p3 = new Person("Peter", "Griffin", LocalDate.of(1978,3,24));
    Person p4 = new Person("Lois", "Griffin", LocalDate.of(1982,7,14));

    personList.add(p1);
    personList.add(p2);
    personList.add(p3);
    personList.add(p4);

    ObjectMapper mapper = new ObjectMapper();
    ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());

    try {
        writer.writeValue(new File(System.getProperty("user.dir")+"/File/Person.json"), personList);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

And my reader class looks like this:

public class Reader {

public void read(){
    ObjectMapper mapper = new ObjectMapper();

    try {
        ArrayList<Person> liste = mapper.readValue(new FileInputStream("File/Personen.json"), ArrayList.class);
        System.out.println("Read: " + liste.get(0));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

The first Object in the list looks like this: Gelesen: {firstname=James, lastname=Bond, birthday={year=1997, month=SEPTEMBER, monthValue=9, dayOfMonth=22, chronology={id=ISO, calendarType=iso8601}, era=CE, dayOfYear=265, dayOfWeek=MONDAY, leapYear=false}}

How do I convert this JSON String back to a java object of the class "person"? Is anything wrong with my serialization/deserialization ?

EDIT: I wanted to check wether my person in the list that is deserialized from the JSON file is the same as the original person so I wrote System.out.println(list.get(0).getFirstname() and then I got an java.lang.ClassCastException: java.base/java.util.LinkedHashMap cannot be cast to Person

Grombaner
  • 41
  • 1
  • 7
  • 1
    Possible duplicate of [How to convert json to ArrayList object in Java?](https://stackoverflow.com/questions/43567612/how-to-convert-json-to-arraylist-object-in-java) – Abhinav Nov 30 '18 at 13:44
  • are you bound to use objectMapper? – Negi Rox Nov 30 '18 at 13:46
  • @NegiRox no it was just the first possibility i found – Grombaner Nov 30 '18 at 13:49
  • Are you getting any exception while deserializing? – Mohamed Anees A Nov 30 '18 at 13:49
  • no nothing but when I write `System.out.println(list.get(0).getFirstname()` to check wether the person in the list matches my original person I get an `java.lang.ClassCastException: java.base/java.util.LinkedHashMap cannot be cast to Person` – Grombaner Nov 30 '18 at 13:54
  • Possible duplicate of [Jackson and generic type reference](https://stackoverflow.com/questions/6846244/jackson-and-generic-type-reference) – Jonathan Nov 30 '18 at 15:02

2 Answers2

1

can you please try this code. i think you need to convert your array list into json format. and retrieve it in json format.

public void write(){
    ArrayList<Person> personList = new ArrayList<>();
    JSONObject obj = new JSONObject();//JSON object.
    Person p1 = new Person("James", "Bond", LocalDate.of(1997,9,22));
    Person p2 = new Person("Santa", "Claus", LocalDate.of(1918,11,6));
    Person p3 = new Person("Peter", "Griffin", LocalDate.of(1978,3,24));
    Person p4 = new Person("Lois", "Griffin", LocalDate.of(1982,7,14));

    personList.add(p1);
    personList.add(p2);
    personList.add(p3);
    personList.add(p4);
    obj.put("list", personList);
    ObjectMapper mapper = new ObjectMapper();
    ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());
    try {
        writer.writeValue(new File(System.getProperty("user.dir")+"/File/Person.json"), obj);
    } catch (IOException e) {
        e.printStackTrace();
    } 
}

public void read(){
    ObjectMapper mapper = new ObjectMapper();
    try {
        JSONObject obj = mapper.readValue(new File("G:\\Personen.json"));
        // Convert JSON string from file to Object
        Person person = mapper.readValue(new File("G:\\Personen.json"), Person.class);
        System.out.println("Read: " + obj);

    } catch (IOException e) {
        e.printStackTrace();
    }
}
Negi Rox
  • 3,828
  • 1
  • 11
  • 18
  • This line in `read()` : `JSONObject obj = mapper.readValue(new FileInputStream("File/Personen.json"));` is not working because there is no `readValue()` method with the parameter `FileInputStream` – Grombaner Nov 30 '18 at 14:11
1

First issue: you are deserializing to ArrayList without any generic type, because of this you are receiving ArrayList of LinkedHashMap. Jackson doesn't know that you are wanting list of person, so it uses LinkedHashMap as type applicable to any json.

To deserialize to list of person you should use:

ArrayList<Person> list = mapper.readValue(new FileInputStream("./person.json"),
                    mapper.getTypeFactory().constructCollectionType(ArrayList.class, Person.class));

Second issues: that you are working with Java 8 time (LocalDate class), but Jackson doesn't know about it. To be able to handle it properly, you need to add JavaTimeModule from jackson-datatype-jsr310 dependency and register it.

So resulting code will be like this:

public void write() {
    ArrayList<Person> personList = new ArrayList<>();

    Person p1 = new Person("James", "Bond", LocalDate.of(1997, 9, 22));
    Person p2 = new Person("Santa", "Claus", LocalDate.of(1918, 11, 6));
    Person p3 = new Person("Peter", "Griffin", LocalDate.of(1978, 3, 24));
    Person p4 = new Person("Lois", "Griffin", LocalDate.of(1982, 7, 14));

    personList.add(p1);
    personList.add(p2);
    personList.add(p3);
    personList.add(p4);

    ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
    ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());

    try {
        writer.writeValue(new File("./person.json"), personList);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void read() {
    ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

    try {
        ArrayList<Person> list = mapper.readValue(new FileInputStream("./person.json"),
                mapper.getTypeFactory().constructCollectionType(ArrayList.class, Person.class));
        System.out.println("Read: " + list.get(0).getFirstname());
    } catch (IOException e) {
        e.printStackTrace();
    }

}
Ulad
  • 1,083
  • 8
  • 17
  • Thank you so much that solved it! I still have a problem with the LocalDate after registering the module but my question here is solved. – Grombaner Dec 01 '18 at 09:22