I have a class structure like below (a simplified version):
public class A {
public int a;
public B b;
public C c;
public D d;
public E e;
}
public class B {
public int a;
}
public class C {
public int a;
public D d;
}
public class D {
public int a;
}
public class E {
public int a;
}
While serializing A
, I'd like to remove a
fields for all classes except the classes included under the C
subtree. Which means I'd like to keep a
fields in C
instance and D
instance (but only for the one under C
). I hope I was clear.
I tried to use MixIns or provide custom serializers but couldn't achieve what I want.
Note that in reality there are too many classes including the a
field and the classes being serialized are auto-generated.
Use JsonFilter
annotation on a field. You can register it via MixIn
feature and enable on given type and getter
methods. See below code:
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
public class JsonApp {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.addMixIn(A.class, AMixIn.class);
SimpleFilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("excludeA", SimpleBeanPropertyFilter.serializeAllExcept("a"));
mapper.setFilterProvider(filterProvider);
System.out.println(mapper.writeValueAsString(new A()));
}
}
@JsonFilter("excludeA")
interface AMixIn {
@JsonFilter("excludeA")
B getB();
@JsonFilter("excludeA")
D getD();
@JsonFilter("excludeA")
E getE();
}
For your POJO
model above code prints:
{
"b" : { },
"c" : {
"a" : 3,
"d" : {
"a" : 4
}
},
"d" : { },
"e" : { }
}
See also:
I was able to solve the problem as follows thanks to the hint @Michał Ziober provided:
// custom serializer for C class, which in fact serializes all fields
public class CNormalSerializer extends JsonSerializer<C> {
@Override
public void serialize(C value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeRawValue(new ObjectMapper().writeValueAsString(value));
}
}
@JsonFilter(JsonFieldFilter.JSON_FILTER)
public class JsonFieldFilter {
public static final String JSON_FILTER = "Json filter";
}
public class X {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
// registered standard C serializer
SimpleModule simpleModule = new SimpleModule();
CNormalSerializer cSerializer = new CNormalSerializer ();
simpleModule.addSerializer(C.class, cSerializer);
objectMapper.registerModule(simpleModule);
// added the 'a' filter
objectMapper.addMixIn(Object.class, JsonFieldFilter.class);
String[] ignorableFieldNames = {"a"};
FilterProvider filters = new SimpleFilterProvider().addFilter(JsonFieldFilter.JSON_FILTER, SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
ObjectWriter writer = objectMapper.writer(filters);
writer.writeValueAsString(new A());
}
}
Put @JsonIgnoreProperties(ignoreUnknown = true)
annotation to your class where you need to skip that field. It will look like this:
@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
public B b;
public C c;
public D d;
public E e;
}
public class B {
public int a;
}
public class C {
public int a;
public D d;
}
public class D {
public int a;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class E {
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.