[英]Jersey serialization/deserialization issue: abstract types can only be instantiated with additional type information
我正在使用球衣进行序列化和反序列化。 我使用jersey在WebLogic上创建了REST通道。 我有结果对象包含抽象类。 Jersey使用此类的实现名称添加结果元数据:
{"order":{"@type":"installationOrder",
但是,同样的球衣,当用于反序列化这些数据时,会尖叫以下内容:
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of ocl.mobile.service.data.order.DetailedOrder, problem: abstract types can only be instantiated with additional type information
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@97eded; line: 1, column: 2] (through reference chain: ocl.mobile.service.OrderDetailsResult["order"])
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:212)
at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:97)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:252)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:356)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:494)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:350)
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2376)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1166)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:410)
at com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy.readFrom(JacksonProviderProxy.java:139)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:553)
... 5 more
但是他自己已经在他序列化的JSON中提供了这些额外的信息。
那么,如何让球衣阅读并理解他创造的这种“@type”注释?
这就是我使用球衣从频道读取数据的方式:
private static Client client;
private static void initClient() {
if (client == null) {
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
Boolean.TRUE);
client = Client.create(clientConfig);
}
}
private static <T> T jsonForResult(String addr, Class<T> expectedClass) {
initClient();
WebResource r = client.resource(addr);
try {
T result = r.get(expectedClass);
return result;
} catch (UniformInterfaceException e) {
log.error(e.getMessage(), e);
return null;
}
}
expectClass在我的例子中是结果类,它包含状态和抽象类“order”,它具有诸如“installationOrder”之类的实现。
试试这个有效
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ExchangeFormat.class, name = "ExchangeFormat"),
@JsonSubTypes.Type(value = TypeStatus.class, name = "TypeStatus"),
})
public abstract class MapperJsonXml <T>
它与xml相同
@XmlSeeAlso({ExchangeFormat.class,TypeStatus.class})
Jersey(或更具体地说,它与POJO映射一起使用的Jackson JSON lib)不会添加@type
除非启用了类型信息包含,通常是通过在抽象类型上添加@JsonTypeInfo
。 所以必须启用这个功能。 也许你可以共享定义DetailOrder
类?
至于问题本身:这通常是由使用的不兼容类型引起的 - 用于反序列化的类型(将JSON值读入POJO)必须使@JsonTypeInfo
注释可见。 例如,您不能只询问java.lang.Object
类型的值,因为它没有这样的注释。 在不知道实际的类定义的情况下,不可能指出具体原因,但这是最可能的解释。
如果您只想排除type
字段,请注释超类@XmlTransient
,如下所述: http : @XmlTransient
这将使序列化工作就像超类字段在子类中一样 - 因此好像没有继承,在这种情况下不会生成type
字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.