给定一个任意Class
个对象,确定杰克逊注册的那个类的子类型的最佳方法是什么?
例如,这是一个简单的案例,其中类Lion
和Penguin
是Animal
的子类型:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(Lion.class),
@JsonSubTypes.Type(Penguin.class)})
public static abstract class Animal {}
@JsonTypeName("Lion")
public static class Lion extends Animal {}
@JsonTypeName("Penguin")
public static class Penguin extends Animal {}
我的梦想功能如下:
List<Class> getSubTypeClasses(Class c) {...}
getSubTypeClasses(Animal.class)
将返回Lion
和Penguin
。
如果Jackson API没有提供获取此信息的便捷方式,我将手动阅读注释,但是知道与任何 {{1实施。
答案 0 :(得分:2)
您可以使用ai.findSubTypes(ac)
代替mapper.getSubtypeResolver().collectAndResolveSubtypes(ac, config, ai)
。
我没有使用已注册的子类型测试它,但查看它应该工作的代码。
答案 1 :(得分:1)
目前没有这样做的机制。但是你可以提交一个添加这样的东西的请求:给定一个基类,返回一组已知的子类型以及用于它们的类型id,以及默认的实现用法。这似乎是一个合理的事情来提供访问。
与此同时(新功能可用于2.3,所以需要一些时间),请查看AnnotationIntrospector
,看看那里有哪些方法,以及jackson-databind
如何使用它构建映射信息。即使没有访问器,您也不必手动编写所有内容。
答案 2 :(得分:0)
感谢StaxMan让我朝着正确的方向努力。这是Jaxen 2.2.3的解决方案:
public static List<Class> getSubtypeClasses(ObjectMapper mapper, Class c) {
return getSubtypeClasses(mapper.getDeserializationConfig(), c);
}
public static List<Class> getSubtypeClasses(MapperConfig config, Class c) {
AnnotationIntrospector ai = config.getAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(c, ai, config);
List<NamedType> subtypes = ai.findSubtypes(ac);
List<Class> result = new ArrayList<>();
if (subtypes != null) {
for (NamedType subtype : subtypes) {
result.add(subtype.getType());
}
}
return result;
}
答案 3 :(得分:0)
要访问超类的SubTypes注释,您可以使用JacksonAnnotationIntrospector:
AnnotationIntrospector annotationInspector = new JacksonAnnotationIntrospector();
JavaType superClassType = TypeFactory.defaultInstance().uncheckedSimpleType(Animal.class);
AnnotatedClass annotatedClass = AnnotatedClass.construct(superClassType,new ObjectMapper().getSerializationConfig());
List<NamedType> subtypes = annotationInspector.findSubtypes(annotatedClass);