I have a POST Rest service through cxf which accepts an object as JSON. The class which it accepts is an abstract class and 2 concrete implementations.
Below is my code:
TestService.java
@Path("/test")
@POST
@Consumes({MediaType.APPLICATION_JSON})
public Response test(TestEntity testEntity)
{
System.out.println(testEntity);
return Response.ok().build();
}
TestEntity.java
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = TestEntityA.class, name = "a"),
@JsonSubTypes.Type(value = TestEntityB.class, name = "b")
})
public abstract class TestEntity
{
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
TestEntityA.java
public class TestEntityA extends TestEntity
{
private String propertyA;
public String getPropertyA()
{
return propertyA;
}
public void setPropertyA(String propertyA)
{
this.propertyA = propertyA;
}
}
TestEntityB.java
public class TestEntityB
{
private String propertyB;
public String getPropertyB()
{
return propertyB;
}
public void setPropertyB(String propertyB)
{
this.propertyB = propertyB;
}
}
The JSON object which i am passing from client is below:
{
"type": "a",
"name": "TestA",
"propertyA": "Property A"
}
With this i get 400 Bad Request error:
Can not construct instance of com.pb.spectrum.profiling.config.entities.TestEntity, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1@7967caad; line: 1, column: 1]
However, when i serialize/deserialize the objects using object mapper in my test cases, it works properly
TestEntity testEntityA = new TestEntityA();
testEntityA.setName("TestA");
((TestEntityA)testEntityA).setPropertyA("Property A");
String json = objectMapper.writeValueAsString(testEntityA);
System.out.println(json);
//This outputs following:
{
"type": "a",
"name": "TestA",
"propertyA": "Property A"
}
TestEntity testEntity = objectMapper.readValue(json,TestEntity.class);
//testEntity is instance of TestEntityA.
System.out.println(testEntity);
What might be going wrong as cxf is not able to desirialize the json correctly?