简体   繁体   English

默认情况下使用Jackson解析为子类

[英]Parse to a Subclass by default with Jackson

I have a class called Product and some subclasses extending it. 我有一个名为Product的类和一些扩展它的子类。 Now in my annotations I have many types, like this: 现在在我的注释中我有很多类型,如下所示:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({@Type(value=RoomProduct.class, name="RoomProduct"),
           @Type(value=GroundProduct.class, name="GroundProduct"),
           })

And then the definition of my Product class. 然后是我的Product类的定义。 What I want to do is if Jackson cannot detect that the field is not complying with any of these structures, to return an 我想要做的是,如果杰克逊不能发现该领域不符合任何这些结构,那么返回

UnknownProduct UnknownProduct

How can I do that with Jackson @Type annotation? 我怎么能用Jackson @Type注释做到这一点? It should be something like putting blank in name or some flag in value which I don't really know (I have tried creating the UnknownProduct which extends Product and putting nothing in the name value with no success. 它应该是在名称中留空或者某些我不知道的值的标志(我已经尝试创建UnknownProduct,它扩展了Product并且没有在名称值中放置任何内容而没有成功。

@JsonTypeInfo has an option to specify default implementation class but after some debugging I found that 'defaultImpl' is broken for the WrapperObject. @JsonTypeInfo有一个指定默认实现类的选项,但经过一些调试后我发现WrapperObject的'defaultImpl'被破坏了。 Configuration: 组态:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.WRAPPER_OBJECT, defaultImpl = UnknownProduct.class)

Jackson implementation (AsWrapperTypeDeserializer): Jackson实现(AsWrapperTypeDeserializer):

public AsWrapperTypeDeserializer(JavaType bt, TypeIdResolver idRes,
        String typePropertyName, boolean typeIdVisible, Class<?> defaultImpl)
{
    super(bt, idRes, typePropertyName, typeIdVisible, null);
}

Note that 'defaultImpl' is passed but it is ignored and configured default class will NOT be used. 请注意,传递'defaultImpl'但会被忽略,并且不会使用配置的默认类。 I didn't find the logged ticket for this problem in jackson's Jira. 我没有在杰克逊的Jira中找到这个问题的登记票。

This is a problem ONLY for the WRAPPER_OBJECT, defaultImpl is working fine for other formats. 这只是WRAPPER_OBJECT的问题,defaultImpl对其他格式工作正常。 But it will change JSON format. 但它会改变JSON格式。 If you can change it -- you can use EXTERNAL_PROPERTY for example with default implementation: 如果您可以更改它 - 您可以使用EXTERNAL_PROPERTY作为默认实现:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type", defaultImpl = UnknownProduct.class)

Another solution: If you have to use WRAPPER_OBJECT then you can configure Jackson not to fail when it find unknown SubType: 另一个解决方案:如果你必须使用WRAPPER_OBJECT,那么你可以配置Jackson在发现未知SubType时不会失败:

objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);

It is not completely the same what you are asking but in that case your product will be null. 它与您要求的不完全相同,但在这种情况下,您的产品将为空。 Probably you can treat null as unknown product. 可能你可以将null视为未知产品。

Update I've filed a Jackson bug: https://github.com/FasterXML/jackson-databind/issues/656 更新我提交了一个Jackson bug: https//github.com/FasterXML/jackson-databind/issues/656

Update This ticket was resolved for 2.3 and 2.4 jackson and hopefully soon you should be able to use it when jars will be re-installed into the maven repository or in a new version. 更新此票据已针对2.3和2.4 jackson解决,希望很快您可以在将罐子重新安装到maven存储库或新版本时使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM