0

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?

Pankaj Dwivedi
  • 159
  • 2
  • 13

0 Answers0