Java 如何使用 Jackson 的 objectMapper 反序列化接口字段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19379863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to deserialize interface fields using Hymanson's objectMapper?
提问by Naman
ObjectMapper
's readValue(InputStream in, Class<T> valueType)
function requires the Class. But how do I use it if the class I am passing internally, is having some Interface as data member.
ObjectMapper
的readValue(InputStream in, Class<T> valueType)
函数需要类。但是如果我在内部传递的类有一些接口作为数据成员,我该如何使用它。
although I can understand the reason behind this exception, as Hymanson is not getting the concrete class of the internal Interface of the passed class, but my question is how to resolve it? how do I deserialize it then? The class I am trying to deserialize is:
虽然我可以理解这个异常背后的原因,因为Hyman逊没有得到传递类的内部接口的具体类,但我的问题是如何解决它?那我该如何反序列化呢?我试图反序列化的类是:
class BaseMetricImpl<N> implements Metric<N> {
protected MetricValueDescriptor descriptor;
}
Here MetricValueDescriptor
is an interface, so this gives me following error : -
这MetricValueDescriptor
是一个界面,所以这给了我以下错误:-
com.fasterxml.Hymanson.databind.JsonMappingException: Can not construct instance of MetricValueDescriptor, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: java.io.ByteArrayInputStream@2ede2c9f; line: 1, column: 2] (through reference chain: SingleValueMetricImpl["descriptor"])
at com.fasterxml.Hymanson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.Hymanson.databind.DeserializationContext.instantiationException(DeserializationContext.java:624)
at com.fasterxml.Hymanson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:115)
at com.fasterxml.Hymanson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:375)
at com.fasterxml.Hymanson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:98)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:308)
at com.fasterxml.Hymanson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.Hymanson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2793)
at com.fasterxml.Hymanson.databind.ObjectMapper.readValue(ObjectMapper.java:1989)
采纳答案by Hari Menon
Hymanson obviously cannot construct the MetricValueDescriptor
object since it is an interface. You will need to have additional information in your json and in your ObjectMapper to tell Hymanson how to construct an object out of it. Here is one way to do it, assuming MVDImpl
is a concrete class which implements MetricValueDescriptor
:
Hymanson 显然不能构造MetricValueDescriptor
对象,因为它是一个接口。您将需要在 json 和 ObjectMapper 中包含其他信息,以告诉 Hymanson 如何从中构造对象。这是一种方法,假设MVDImpl
是一个实现的具体类MetricValueDescriptor
:
You can tell Hymanson the required type information through a field in the json itself, say "type"
. To do this, you need to use JsonTypeInfo
and JsonSubTypes
annotations in your interface. For example,
您可以通过 json 本身中的字段告诉 Hymanson 所需的类型信息,例如"type"
. 为此,您需要在界面中使用JsonTypeInfo
和JsonSubTypes
注释。例如,
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@Type(value = MVDImpl.class, name = "mvdimpl") })
interface MetricValueDescriptor
{
...
}
You will need to add a "type":"mvdimpl"
field in your json as well.
您还需要"type":"mvdimpl"
在 json 中添加一个字段。
I was going to point you to the official docfor more info, but then I found an excellent blog covering this topic - Deserialize JSON with Hymanson. It covers this topic pretty comprehensively and with examples. So you should definitely read it if you need more customisation.
我打算将您指向官方文档以获取更多信息,但后来我发现了一个很好的博客,涵盖了这个主题 - Deserialize JSON with Hymanson。它非常全面地涵盖了这个主题,并附有示例。所以如果你需要更多的定制,你一定要阅读它。