2

I want to deserialize this JSON "{\"m\":{\"Test\":{\"nombre\":\"jose\",\"apellidos\":\"jose\",\"edad\":30}}}" in to PersonaContainer.

    public class Persona {
    private String nombre;
    private String apellidos;
    private int edad;

    ... getters and setters;

}

    public class PersonaContainer {

    private Map m = new HashMap<String,Persona>();

    public Map getM() {
        return m;
    }

    public void setM(Map m) {
        this.m = m;
    }   

}

Then I, create an Object of persona and put it inside persona container with the next code

    public class MyJSONTest {

    public static void main(String args[]) {
        ObjectMapper mapper = new ObjectMapper();
        Map m = new HashMap<String,persona>();

        Persona p = new Persona();
        p.setNombre("jose");
        p.setApellidos("jose");
        p.setEdad(30);
        m.put("Test", p);

        PersonaContainer per = new PersonaContainer();
        per.setM(m);

        //convert Map to json string
        try {
            System.out.println(mapper.writeValueAsString(per));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // convert json to Map 
        String json = "{\"m\":{\"Test\":{\"nombre\":\"jose\",\"apellidos\":\"jose\",\"edad\":30}}}";
        try {
            PersonaContainer pers = mapper.readValue(json, PersonaContainer.class);
            Persona per1 = (Persona) pers.getM().get("Test");
            System.out.println(per1.getNombre());
        } catch (Exception e) {
            e.printStackTrace();
        }
 }

}

After the serialization, I use ObjectMapper to get deserialize JSON in to a PersonaContainer Object, but when I try to obtain "Test" from HashMap "m" and cast it to Person Object i get this error:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to persona
    at MyJSONTest.main(MyJSONTest.java:52)

any advice please?

Jose
  • 116
  • 1
  • 12
  • 2
    Don't use raw types. – Sotirios Delimanolis Jul 16 '15 at 17:05
  • 1
    In `PersonaContainer`, the attribute `m`, its getter and its setter all need to use `Map`. – fps Jul 16 '15 at 18:10
  • Ok, I get it, it works fine, but if I extend persona from humano @FedericoPeraltaSchaffner – Jose Jul 16 '15 at 18:29
  • 1
    @Jose See [here](http://wiki.fasterxml.com/JacksonPolymorphicDeserialization) and [here](http://stackoverflow.com/questions/24263904/deserializing-polymorphic-types-with-jackson) – fps Jul 16 '15 at 18:30
  • 1
    Thanks, you where right i add ´@JsonTypeInfo´ and ´@JsonSubTypes´ Annotations and this tells jackson how to deserilize this kind of objects. @Federico Peralta Schaffner – Jose Jul 16 '15 at 21:54

1 Answers1

2

Given only

private Map m = ...;

Jackson has no idea what types you expect for the Map's keys and values. It therefore uses its defaults. For regular objects, it uses LinkedHashMap. In other words, it will deserialize

{"nombre":"jose","apellidos":"jose","edad":30}

into a LinkedHashMap instance. When you try to use it as a Persona, it fails with the ClassCastException.

Instead, don't use raw types. Declare the Map with proper generic arguments.

private Map<String, Persona> m = ...;

Note that Spring will deserialize the corresponding JSON (m) into a LinkedHashMap, not a HashMap. If you want a HashMap, declare the field with the type HashMap.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724