Jackson adding additional fields to JSON throws java.util.concurrent.CompletionException:

BATMAN_2008

Neues Mitglied
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`:

The following is the sample code:
Java:
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;
}


Java:
@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;
}

Java:
@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;
}


Code:
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_field", "some data");
            jgen.writeObjectField("my_extra_field", "some 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();
        }
    }
}

Java:
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.
 
Y

yfons123

Gast
When DefaultTyping.NON_FINAL is enable, the objectMapper will use the method "serializeWithType" defined in the class "JsonSerializer" to do the serialiaztion works if a custom serializer is defined.
So to solve the problem, you need to override the method "serializeWithType".
 

BATMAN_2008

Neues Mitglied
@yfons123 Thanks a lot for your response. If possible can you please one small example or some suggestion because I tried to add the following things to my ObjectMapper but this does not seem to fix the issue?

objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
 

Ähnliche Java Themen

Neue Themen


Oben