Reputation: 22847
I'm using jersey for both serialization and deserialization. I've made REST channel on WebLogic using jersey. I have result object with contains abstract class. Jersey adds to the result metadata with this class'es implementation name:
{"order":{"@type":"installationOrder",
However, the same jersey, when using to deserialize this data, is screaming the following:
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
but he himself have provided this additional information in the JSON he has serialized.
So, how to make jersey to read and understand this "@type" annotations he have created?
This is how I'm using jersey to read data from channel:
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;
}
}
The expectedClass is in my case the class of result, which contains status and the abstract class "order", which has implementations such as "installationOrder".
Upvotes: 8
Views: 31861
Reputation: 11
If you just want to just exclude type
field, annotate the superclass @XmlTransient
, as mentioned here: http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html
That will make the serialization work as if the superclass fields were in the child class - thus as if there was no inheritance, in which case the type
field won't be produced.
Upvotes: 1
Reputation: 1761
try this it works
@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>
it's the same with xml
@XmlSeeAlso({ExchangeFormat.class,TypeStatus.class})
Upvotes: 12
Reputation: 116522
Jersey (or more specifically, Jackson JSON lib it uses with POJO mapping) does not add @type
unless type information inclusion is enabled, usually by adding @JsonTypeInfo
on an abstract type. So something must have enabled this. Maybe you can share definition DetailOrder
class?
As to problem itself: this is usually caused by incompatible types used -- type used for deserialization (reading JSON value into POJO) must be such that @JsonTypeInfo
annotation is visible. You can not, for example, just ask for value of type java.lang.Object
, since it does not have such annotation. Without knowing actual class definitions it is not possible to point to specific cause, but this is the most likely explanation.
Upvotes: 6