I am using Jackson-ObjectMapper
to create the JSON data according to my POJO. I would like to add some additional properties to my JSON without modifying the POJO.
Since the POJO has been added as a dependency in my project I cannot modify it but I need some additional fields in JSON. Is there a way to add new key-value pair to JSON without making modifications to Java POJO? I am currently using Jackson 2.13.2 latest version dependencies: jackson-core, jackson-databind, jackson-annotations, jackson-datatype-jdk8
Following is the Java code:
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;
public class Test {
public static void main(String args[]) throws Exception{
ObjectMapper objectMapper = new ObjectMapper();
CustomClass cc = new CustomClass();
cc.setName("Batman");
cc.setAge(30);
System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(cc));
}
@Getter
@Setter
public static class CustomClass {
private String name;
private int age;
}
}
This is providing me with the JSON:
{
"name" : "Batman",
"age" : 30
}
I would like to obtain the JSON that looks something like this, but do not want to add new fields job and company to my CustomClass
POJO.
{
"name" : "Batman",
"age" : 30,
"job" : "HR",
"company": "New"
}
I tried to do something like this: https://www.jdoodle.com/a/z99 but I get the error: Type id handling not implemented for type package.ClassName (by serializer of type package.CustomModule$CustomClassSerializer)
You can try like below in the controller level, (it would be better to manipulate the response by using the Interceptor or Filter)
@GetMapping
public ObjectNode test() throws JsonProcessingException {
CustomClass customClass = new CustomClass();
customClass.setAge(30);
customClass.setName("Batman");
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(customClass);
ObjectNode nodes = mapper.readValue(jsonStr, ObjectNode.class);
nodes.put("job", "HR ");
nodes.put("company", "New ");
return nodes;
}
Response:
{
name: "Batman",
age: 30,
job: "HR ",
company: "New "
}
Your new test driver is below,
public static void main(String[] args) throws JsonProcessingException {
CustomClass customClass = new CustomClass();
customClass.setAge(30);
customClass.setName("Batman");
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(customClass);
ObjectNode nodes = mapper.readValue(jsonStr, ObjectNode.class);
nodes.put("job", "HR ");
nodes.put("company", "New ");
System.out.println(nodes);
}
Output: {"name":"Batman","age":30,"job":"HR ","company":"New "}
Updated
but I get the error: Type id handling not implemented for type package.ClassName (by serializer of type package.CustomModule$CustomClassSerializer)
Write new object fields "job" and "company" to your custom class serializer.
public class Test {
public static void main(String args[]) throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new CustomModule());
CustomClass cc = new CustomClass();
cc.setAge(30);
cc.setName("Batman");
StringWriter sw = new StringWriter();
objectMapper.writeValue(sw, cc);
System.out.println(sw.toString());
}
public static class CustomModule extends SimpleModule {
public CustomModule() {
addSerializer(CustomClass.class, new CustomClassSerializer());
}
private static class CustomClassSerializer extends JsonSerializer {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// Validate.isInstanceOf(CustomClass.class, value);
jgen.writeStartObject();
JavaType javaType = provider.constructType(CustomClass.class);
BeanDescription beanDesc = provider.getConfig().introspect(javaType);
JsonSerializer<Object> serializer = BeanSerializerFactory.instance.findBeanSerializer(provider,
javaType, beanDesc);
// this is basically your 'writeAllFields()'-method:
serializer.unwrappingSerializer(null).serialize(value, jgen, provider);
jgen.writeObjectField("job", "HR ");
jgen.writeObjectField("company", "New ");
jgen.writeEndObject();
}
}
}
}
Output: {"name":"Batman","age":30,"job":"HR ","company":"New "}