Java 在Jackson(和MrBean)反序列化时使用多态性
我正在使用Jackson将一些JSON反序列化为JavaPOJO。我用我的对象映射器注册了MrBean模块,所以我所要做的就是定义一组接口,然后基于这些接口自动生成POJO 我希望有一个凭据接口,其中包含扩展它的各种类型的凭据,例如UsernamePasswordCredentials和CertificateFileCredentials 在没有任何注释或其他咒语的情况下进行此操作,以使其正常工作,在单元测试中会出现以下错误:Java 在Jackson(和MrBean)反序列化时使用多态性,java,json,polymorphism,jackson,deserialization,Java,Json,Polymorphism,Jackson,Deserialization,我正在使用Jackson将一些JSON反序列化为JavaPOJO。我用我的对象映射器注册了MrBean模块,所以我所要做的就是定义一组接口,然后基于这些接口自动生成POJO 我希望有一个凭据接口,其中包含扩展它的各种类型的凭据,例如UsernamePasswordCredentials和CertificateFileCredentials 在没有任何注释或其他咒语的情况下进行此操作,以使其正常工作,在单元测试中会出现以下错误: org.codehaus.jackson.map.exc.Unrec
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "username" (Class org.codehaus.jackson.generated.SCRUBBED.Credentials), not marked as ignorable
at [Source: java.io.StringReader@e0b6f5; line: 32, column: 29] (through reference chain: HostConfiguration["hostDefinitions"]->HostDefinition["credentials"]->Credentials["username"])
我也犯了同样的错误
错误是有道理的;Jackson正在尝试将我的JSON文件的内容映射到一个空接口。然而,我(也许是天真地)希望Jackson寻找扩展基本凭据接口的接口,并尝试将这些接口中的字段与它在JSON对象中找到的字段相匹配
我在Jackson wiki上看到了一些使用JSON对象中的元信息的示例,例如,用“@class”:“foo.bar.CertificateFileCredentials”
装饰对象,但我更愿意避免这些,因为我的JSON输入将由其他服务自动生成,其他服务不必知道我服务的任何内部内容
谢谢 您将如何定义实际的实现类?作为附加接口?这些应该正确生成;但问题是在反序列化过程中:如果有多种选择,反序列化程序必须有某种方法来找出要使用的实际类型。
为此,正如您所注意到的,建议使用
@JsonTypeInfo
。如何定义实际的实现类?作为附加接口?这些应该正确生成;但问题是在反序列化过程中:如果有多种选择,反序列化程序必须有某种方法来找出要使用的实际类型。
为此,正如您所注意到的,建议使用
@JsonTypeInfo
。实际上,该技术也适用于您的目的,即使您不控制生成JSON的服务
在使用@JsonTypeInfo时,保存类名是一个非常简单的默认设置,但是Jackson允许您根据自己的喜好进行自定义
例如,假设服务生成如下所示的JSON:
{ meows: 400, furColor: "green", species: "cat" }
然后您可以定义这些接口来正确地转换它
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY,property="species")
@JsonSubTypes({
@JsonSubTypes.Type(value=Feline.class, name="cat")
})
public interface Animal {
public String getFurColor();
}
@JsonTypeName("cat")
public interface Feline extends Animal {
@JsonProperty("meows") // just to have an example of a renamed property...
public long getMeowingVolumeInDecibels();
}
然后,您应该在反序列化时在运行时自动获得正确的java类型,并根据运行时类型自动生成“species”属性。希望有帮助 实际上,该技术也可以很好地满足您的需要,即使您不控制生成JSON的服务 在使用@JsonTypeInfo时,保存类名是一个非常简单的默认设置,但是Jackson允许您根据自己的喜好进行自定义 例如,假设服务生成如下所示的JSON:
{ meows: 400, furColor: "green", species: "cat" }
然后您可以定义这些接口来正确地转换它
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY,property="species")
@JsonSubTypes({
@JsonSubTypes.Type(value=Feline.class, name="cat")
})
public interface Animal {
public String getFurColor();
}
@JsonTypeName("cat")
public interface Feline extends Animal {
@JsonProperty("meows") // just to have an example of a renamed property...
public long getMeowingVolumeInDecibels();
}
然后,您应该在反序列化时在运行时自动获得正确的java类型,并根据运行时类型自动生成“species”属性。希望有帮助