Jackson 如何在不更改默认 POJO 的情况下在序列化期间添加其他属性?
Jackson How to add additional properties during searlization without making changes to default POJO?
我正在使用 Jackson-ObjectMapper
根据我的 POJO 创建 JSON 数据。我想在不修改 POJO 的情况下向 JSON 添加一些额外的属性。
由于 POJO 已作为依赖项添加到我的项目中,我无法修改它,但我需要 JSON 中的一些附加字段。有没有办法在不修改 Java POJO 的情况下向 JSON 添加新的键值对?我目前使用的是 Jackson 2.13.2 最新版本依赖:jackson-core, jackson-databind, jackson-annotations, jackson-datatype-jdk8
以下是Java代码:
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;
}
}
这为我提供了 JSON:
{
"name" : "Batman",
"age" : 30
}
我想获得看起来像这样的 JSON,但不想向我的 CustomClass
POJO 添加新的字段工作和公司。
{
"name" : "Batman",
"age" : 30,
"job" : "HR",
"company": "New"
}
我试图做这样的事情:https://www.jdoodle.com/a/z99 但我收到错误:Type id handling not implemented for type package.ClassName (by serializer of type package.CustomModule$CustomClassSerializer)
你可以在controller级别尝试如下,(最好使用Interceptor或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;
}
响应:
{
name: "Batman",
age: 30,
job: "HR ",
company: "New "
}
你的新试驾如下,
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);
}
输出: {"name":"Batman","age":30,"job":"HR ","company":"New "}
已更新
but I get the error: Type id handling not implemented for type
package.ClassName (by serializer of type
package.CustomModule$CustomClassSerializer)
将新对象字段“工作”和“公司”写入您的自定义 class 序列化程序。
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();
}
}
}
}
输出: {"name":"Batman","age":30,"job":"HR ","company":"New "}
我正在使用 Jackson-ObjectMapper
根据我的 POJO 创建 JSON 数据。我想在不修改 POJO 的情况下向 JSON 添加一些额外的属性。
由于 POJO 已作为依赖项添加到我的项目中,我无法修改它,但我需要 JSON 中的一些附加字段。有没有办法在不修改 Java POJO 的情况下向 JSON 添加新的键值对?我目前使用的是 Jackson 2.13.2 最新版本依赖:jackson-core, jackson-databind, jackson-annotations, jackson-datatype-jdk8
以下是Java代码:
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;
}
}
这为我提供了 JSON:
{
"name" : "Batman",
"age" : 30
}
我想获得看起来像这样的 JSON,但不想向我的 CustomClass
POJO 添加新的字段工作和公司。
{
"name" : "Batman",
"age" : 30,
"job" : "HR",
"company": "New"
}
我试图做这样的事情:https://www.jdoodle.com/a/z99 但我收到错误:Type id handling not implemented for type package.ClassName (by serializer of type package.CustomModule$CustomClassSerializer)
你可以在controller级别尝试如下,(最好使用Interceptor或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;
}
响应:
{
name: "Batman",
age: 30,
job: "HR ",
company: "New "
}
你的新试驾如下,
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);
}
输出: {"name":"Batman","age":30,"job":"HR ","company":"New "}
已更新
but I get the error: Type id handling not implemented for type package.ClassName (by serializer of type package.CustomModule$CustomClassSerializer)
将新对象字段“工作”和“公司”写入您的自定义 class 序列化程序。
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();
}
}
}
}
输出: {"name":"Batman","age":30,"job":"HR ","company":"New "}