Джексона VisibilityChecker
предоставляет простой способ фильтрации определенных свойств, особенно потому, что он позволяет вам проверять видимость (равно «будет сериализовано или нет») для каждого метода / поля в отдельности.
По крайней мере, это помогает на этапе сериализации.
Вот что я сделал (используя версию 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) {
// names must be equal
if (! subMethod.getName().equals(superMethod.getName())) return false;
// return types must be assignable
if (! superMethod.getReturnType().isAssignableFrom(subMethod.getReturnType())) return false;
// parameters must be equal
if (! Arrays.equals(subMethod.getParameterTypes(), superMethod.getGenericParameterTypes())) return false;
// classes must be assignable
return superMethod.getDeclaringClass().isAssignableFrom(subMethod.getDeclaringClass());
}
}
Основная идея заключается в использованиистандарт VisibilityChecker
и расширить его путем проверки, объявлен ли метод в одном из заданных интерфейсов.
Средство проверки применяется к экземпляру ObjectMapper с использованием следующего фрагмента:
ObjectMapper om = new ObjectMapper();
om.setVisibilityChecker(new InterfaceVisibilityChecker(
I1.class,
I2.class,
Ia.class,
Ib.class,
Ic.class
));
Некоторые комментарии к решению выше:
- Проверка не завершена, такие методы, как
isIsGetterVisible
или isFieldVisible
, могут обрабатываться аналогичным образом, если это необходимо.. isOverwriteMethod
вообще не оптимизирован, его проверки могут быть кэшированы.