在Java中序列化选择性类变量



我需要根据条件序列化一些字段。

例如,我有以下课程。

public class ClassExample
{
private String id;
private String type;
private String string_1;
private String string_2;
}

因此,假设该类型可以接收两个值,"type_1"或"type_2",并且string_1和string_2将始终为null(它们将由另一个应用程序更改(。

我想使用Jackson来序列化它,我想:

1( 如果是type_1,字符串_1会显示在JSON中,字符串_2则不会。

2( 如果是类型_2,字符串_2会显示在JSON中,字符串_1则不会。

有办法做到这一点吗?

提前感谢

一个字段依赖于另一个字段的为空性可能是一个迹象,表明您应该将类拆分为2。您可以用两个类来代替一个包含两个可能值的类型字段,而不必在其中包含任何类型字段。因此不需要自定义序列化程序。

据我所知,您希望序列化符合条件的类字段。有多种方法可以解决这个问题,因为你想要的解决方案没有使用自定义序列化程序,这里有一个解决方案:-

该解决方案基于Jackson的FilterProvider。

建议:-

  1. 使用自定义序列化程序,如果您有非常严格的约束,请使用上面提到的解决方案
  2. 请将类型设为枚举,并根据相应的类型操作进行不同的实现

如果你能详细说明你的用例,我可以推荐一个更好的解决方案

解决方案:-

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Getter
@Setter
@Slf4j
@AllArgsConstructor
@JsonFilter("myFilter")
public class ClassExample {
private String id;
private String type;
private String string_1;
private String string_2;
private static final ObjectMapper om = new ObjectMapper();
private static final PropertyFilter theFilter = new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
SerializerProvider provider, PropertyWriter writer)
throws Exception {
if (include(writer)) {
if (!(writer.getName().equals("string_1") || writer.getName().equals("string_2"))) {
writer.serializeAsField(pojo, jgen, provider);
return;
}
String type = ((ClassExample) pojo).getType();
if ("type_1".equals(type) && (writer.getName().equals("string_1"))) {
writer.serializeAsField(pojo, jgen, provider);
} else if ("type_2".equals(type) && (writer.getName().equals("string_2"))) {
writer.serializeAsField(pojo, jgen, provider);
}
} else if (!jgen.canOmitFields()) { // since 2.3
writer.serializeAsOmittedField(pojo, jgen, provider);
}
}
@Override
protected boolean include(BeanPropertyWriter writer) {
return true;
}
@Override
protected boolean include(PropertyWriter writer) {
return true;
}
};
public String toString() {
try {
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
return om.writer(filters).writeValueAsString(this);
} catch (Exception e) {
log.error("error while serialisation", e);
return "";
}
}
public static void main(String[] args) {
System.out.println(new ClassExample("123", "type_1", "1", "2"));
}
}

输出:

If type is type_1 then {"id":"123","type":"type_1","string_1":"1"}
If type if type_2 then {"id":"123","type":"type_2","string_2":"2"}

最新更新