3

给定一个任意Class对象,确定向 Jackson 注册的该类的子类型的最佳方法是什么?

例如,这是一个简单的例子,其中 classesLionPenguin是 的子类型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)会返回LionPenguin

如果 Jackson API 不提供获取此信息的便捷方法,我将手动阅读注释,但如果知道与任何 AnnotationIntrospector实现兼容的技术会很高兴。

4

4 回答 4

2

Instead of ai.findSubTypes(ac) you may use mapper.getSubtypeResolver().collectAndResolveSubtypes(ac, config, ai). I've not tested it with registered subtypes but looking at the code it should work.

于 2013-12-18T14:20:24.903 回答
1

目前没有这样做的机制。但是你可以提出添加这样的请求:给定一个基类,返回一组已知的子类型以及用于它们的类型 ID,以及默认的实现使用。提供访问权限似乎是一件合理的事情。

同时(2.3 可能会提供新功能,因此需要一些时间),看看AnnotationIntrospector那里有哪些可用的方法,以及如何jackson-databind使用它来构建映射信息。即使没有访问器,您也不必手动编写所有这些内容。

于 2013-10-01T23:06:03.457 回答
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;
}
于 2013-10-02T00:40:33.807 回答
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);
于 2016-06-07T08:00:11.467 回答