我有以下内容:
接口I1扩展Ia,Ib,Ic
接口I2。
C类实现I1,I2。这个班级也有自己的制定者和吸气剂。
C cInstance = new C():
//Jackson
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new File("somefile.json"), cInstance);
//Gson
Gson gson = new Gson();
String json = gson.toJson(cInstance);
输出将根据C的属性及其继承的内容序列化cInstance。 但是,我喜欢将属性序列化为根据I1中的setter / getter(仅在I1接口中表示的cInstance属性)。
我怎么能和杰克逊知道我有太多类有相同问题的课程,而且我无法修改课程定义或添加注释。
同样的问题适用于反序列化(根据接口反序列化)
由于
答案 0 :(得分:3)
首先,即使不直接添加注释,也可以随时附加“混合注释”(参见wiki page)。有了这个,使用的注释将是:
@JsonSerialize(as=MyInterface.class)
但如果您不想使用混合,可以强制使用特定类型
objectMapper.typedWriter(MyInterface.class).writeValue(....)
答案 1 :(得分:0)
杰克逊的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
根本没有优化,它的检查可以缓存。