JSON-Jackson - Ausnahme beim serialisieren eine polymorphe Klasse mit benutzerdefinierte serializer

Ich bin derzeit migrieren von code aus Jackson 1.x Jackson 2.5 json-mapper und einen langen ein problem, das nicht da war in 1.x.

Dies ist die setup (siehe code unten):

  • Schnittstelle IPet
  • class Hund implements IPet
  • IPet ist annotiert mit @JsonTypeInfo und @JsonSubTypes
  • Klasse Mensch hat eine Eigenschaft mit dem Typ " IPet ist annotiert mit @JsonSerialize(using=CustomPetSerializer.class)

Das problem:
Wenn ich serialisieren wird eine Instanz der Hund es funktioniert wie erwartet (auch die Typ-info Hinzugefügt, um die json-string von Jackson).
Wenn ich mir jedoch die Serialisierung einer Instanz des Menschlichen Klasse eine exception geworfen wird sagen:

com.fasterxml.jackson.databind-Methode.JsonMappingException: Typ-id-handling
nicht implementiert für Typ com.pet.Hund (über die Referenz-Kette:
com.Menschlichen["pet"])

Die serialize (...) - Methode der CustomPetSerializer Klasse wird nicht aufgerufen (getestet mit einem Haltepunkt).

Code:

IPet Umsetzung:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({
     @JsonSubTypes.Type(value=Dog.class,    name="dog")
    //,@JsonSubTypes.Type(value=Cat.class,  name="cat")
    //more subtypes here...
})
public interface IPet
{
    public Long getId();
    public String getPetMakes();
}

Hund Implementierung:

public class Dog implements IPet
{
    @Override
    public String getPetMakes()
    {
        return "Wuff!";
    }

    @Override
    public Long getId()
    {
        return 777L;
    }
}

Mensch besitzt einen Hund:

public class Human
{
    private IPet pet = new Dog();

    @JsonSerialize(using=CustomPetSerializer.class)
    public IPet getPet()
    {
        return pet;
    }
}

CustomPetSerializer Umsetzung:

public class CustomPetSerializer extends JsonSerializer<IPet>
{
    @Override
    public void serialize(IPet value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException
    {
        if(value != null && value.getId() != null)
        {
            Map<String,Object> style = new HashMap<String,Object>();
            style.put("age", "7");
            gen.writeObject(style);
        }
    }
}

JUnit-test Methode:

@Test
public void testPet() throws JsonProcessingException
{
    ObjectMapper mapper = new ObjectMapper();

    Human human = new Human();

    //works as expcected
    String json = mapper.writeValueAsString(human.getPet());
    Assert.assertNotNull(json);
    Assert.assertTrue(json.equals("{\"type\":\"dog\",\"id\":777,\"petMakes\":\"Wuff!\"}"));

    //throws exception: Type id handling not implemented for type com.pet.Dog (through reference chain: com.Human["pet"])
    json = mapper.writeValueAsString(human);    //exception is thrown here
    Assert.assertNotNull(json);
    Assert.assertTrue(json.contains("\"age\":\"7\""));
}
Schreibe einen Kommentar