Jackson VisibilityChecker provides an easy way to filter certain properties, especially because it allows you to check visibility (whether it will be serialized or not) for each method / field separately.
At the very least, it helps for the serialization phase.
Here is what I did (using Jackson version 1.9.11):
import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.introspect.AnnotatedMethod; import org.codehaus.jackson.map.introspect.VisibilityChecker; public static class InterfaceVisibilityChecker extends VisibilityChecker.Std { private final Set<Method> visibleMethods; public InterfaceVisibilityChecker(Class<?>... clazzes) { super(JsonAutoDetect.Visibility.PUBLIC_ONLY); this.visibleMethods = new HashSet<>(); for (Class<?> clz : clazzes) { this.visibleMethods.addAll(Arrays.asList(clz.getMethods())); } } @Override public boolean isGetterVisible(Method m) { return super.isGetterVisible(m) && isVisible(m); } @Override public boolean isGetterVisible(AnnotatedMethod m) { return isGetterVisible(m.getAnnotated()); } private boolean isVisible(Method m) { for (Method visiMthd : visibleMethods) { if (isOverwriteMethod(m, visiMthd)) return true; } return false; } private boolean isOverwriteMethod(Method subMethod, Method superMethod) {
The basic idea is to use the standard VisibilityChecker and extend it by checking whether the method is declared in one of the specified interfaces.
The controller is applied to the ObjectMapper instance using the following snippet:
ObjectMapper om = new ObjectMapper(); om.setVisibilityChecker(new InterfaceVisibilityChecker( I1.class, I2.class, Ia.class, Ib.class, Ic.class
));
Some comments on the solution above:
- Validation is not complete; methods like
isIsGetterVisible or isFieldVisible can be handled in the same way if necessary. isOverwriteMethod is not optimized at all, checks can be cached.
source share