Jersey serialization / deserialization issue: abstract types can only be created with additional type information

I use jerseys for serialization and deserialization. I made a REST channel on WebLogic using a shirt. I have a result object containing an abstract class. Jersey adds to the result metadata named implementation of this class:

{"order":{"@type":"installationOrder", 

However, the same jersey when used to deserialize this data yells 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@97ed ed; 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 provided this additional information in JSON, which he serialized.

So, how to get Mike to read and understand these @type annotations that he created?

Here's how I use knitwear to read data from a 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 expected class in my case is the result class, which contains the status and the abstract class "order", which has implementations such as "installationOrder".

+6
source share
3 answers

A jersey (or more specifically the Jackson JSON lib that it uses with a POJO mapping) does not add @type if type information is included, usually adding @JsonTypeInfo to the abstract type. So something had to do it. Maybe you can share the definition of the DetailOrder class?

As for the problem itself: this is usually caused by incompatible types - the type used for deserialization (reading the JSON value in POJO) should be such that the @JsonTypeInfo annotation is @JsonTypeInfo . For example, you cannot just set a value of type java.lang.Object , since it does not have such an annotation. Without knowing the actual definitions of classes, it is impossible to indicate a specific reason, but this is the most likely explanation.

+6
source

try this one 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}) 
+10
source

If you just want to exclude the type field, annotate the superclass @XmlTransient , as indicated here: http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html

This will cause serialization to work as if the superclass fields were in the child class - in such a way as if there was no inheritance, in which case the type field would not be created.

+1
source

Source: https://habr.com/ru/post/907241/


All Articles