Stelios Koussouris
Stelios Koussouris

Reputation: 145

JAXB Annotated Classes for JSON (Jackson) containing abstract property

With the following classes, which make up the JSON message structure I transfer to the client side after a JAX-RS call (CXF), I receive

org.apache.cxf.jaxrs.client.ClientWebApplicationException: .Problem with reading the response message, class : class bg.vivacom.sel.dto.SELResponse, ContentType : application/json.
...
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of bg.vivacom.sel.dto.SELDTO, problem: abstract types can only be instantiated with additional type information
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@16edbe39; line: 1, column: 157] (through reference chain: bg.vivacom.sel.dto.SELResponse["dto"])

The returned object contains property dto which is an interface

@XmlRootElement(name = "SELResponse")
public class SELResponse implements Serializable{

@XmlElement(name = "corelationID")
private String corelationID;

@XmlElement(name = "responseTimeStamp")  
private String responseTimeStamp;

@XmlElement(name = "respStatusCode")  
private String respStatusCode;

@XmlElement(name = "respStatusMessage")  
private String respStatusMessage;

@XmlElement(name = "processStatus")  
private ProcessStatus processStatus;

@XmlElement(name = "dto")  
private SELDTO dto; 

The interface

public interface SELDTO extends Serializable {

is a way to include a number of different DTOs in my answer depending on the request, such as

@XmlRootElement(name = "customerProfile")
public class CustomerProfileDTO implements SELDTO {

@XmlElement(name = "customerCode")
private String customerCode;
...

and

@XmlRootElement(name = "sms")
public class SmsDTO implements SELDTO {

@XmlElement(name = "From")
private String from;
...

Any ideas how else I have to annotate the classes so that the response can be correctly set to the specific object type. I understand that it requires additional information as at the time it re-creates the dto object it doesn't know its type so I have tried to annotate the interface as follows:

@XmlSeeAlso({CustomerProfileDTO.class, SmsDTO .class})
public interface SELDTO extends Serializable {

but I still get the issue. Any thoughts would be appreciated it.

Upvotes: 2

Views: 2103

Answers (1)

StaxMan
StaxMan

Reputation: 116512

I would recommend using Jackson annotation '@JsonTypeInfo' for this case.

But if you must use JAXB annotations, use @XmlElements or @XmlElementRefs similar to how you'd use them with JAXB/XML:

     @XmlElements({
             @XmlElement(type=SubClass1.class, name="sub1"),
             @XmlElement(type=SubClass2.class, name="sub2")
     })

note that you must include specific mapping to possible subtypes here.

Upvotes: 1

Related Questions