I am using Jackson to serialize my Java POJO classes. In addition to fields, I have in Java POJO, I would like to add some additional information in JSON I am writing my own custom CustomClassSerializer
. If I use this class and register to ObjectMapper
then I get the error:
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type org.acme.Tiger (by serializer of type org.acme.CustomModule$CustomClassSerializer)
I am unable to understand what might be going wrong here. If I remove the custom registered model then everything works perfectly.
Can someone please let me know what may be the cause of this issue? I am currently using Jackson 2.13.2 latest version dependencies: jackson-core, jackson-databind, jackson-annotations, jackson-datatype-jdk8
:
Following is the sample code:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.*;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = Bat.class, name = "Bat"),
@JsonSubTypes.Type(value = Tiger.class, name = "Tiger")})
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Animal {
private String type;
private String name;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonTypeName("Tiger")
public class Tiger extends Animal {
private String livingType;
private String foundIn;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonTypeName("Bat")
public class Bat extends Animal{
private String livingType;
private String foundIn;
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerFactory;
import java.io.IOException;
public class CustomModule extends SimpleModule {
public CustomModule() {
addSerializer(Tiger.class, new CustomClassSerializer());
}
private static class CustomClassSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStartObject();
jgen.writeObjectField("my_extra_field1", "some data");
jgen.writeObjectField("my_extra_field2", "some more data");
JavaType javaType = provider.constructType(Tiger.class);
BeanDescription beanDesc = provider.getConfig().introspect(javaType);
JsonSerializer<Object> serializer = BeanSerializerFactory.instance.createSerializer(provider, javaType);
serializer.unwrappingSerializer(null).serialize(value, jgen, provider);
jgen.writeEndObject();
}
}
}
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestMain {
public static void main(String[] args) throws JsonProcessingException {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.registerModule(new CustomModule());
Tiger tiger = new Tiger();
tiger.setType("Tiger");
tiger.setName("Shera");
tiger.setFoundIn("Ground");
tiger.setLivingType("Tree");
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(tiger));
}
}
I would like to know what are the causes for the above-mentioned exception.
@JsonSerialize(using=CustomPetSerializer.class)
on the field but in my case I am trying to add additional fields to my JSON which does not exist in the POJO so I am not understanding where to add this Custom created class. Can you please let me know how to incorporate this answer in my current code? – Aviary