0

I am developing restful web services using JAX-RS and Apache CXF. Jackson is in the classpath but I am not sure if Apache CXF is using the same to serialise/deserialise classes. I am trying to POST an object (DTO) which is an inner static class and looks like this :

  @XmlRootElement(name = "dto")
  public static class DTO implements Comparable<DTO>, Cloneable{

  private long id;
  private String name; 
  private Collection<Class1> obj1;
  private Collection<Class2> obj2;
  @JsonDeserialize(as=SomeConcreteClass.class)
  private Collection<String, Class3> obj3;

  //getters and setters
  }

Class1, Class2 and Class3 are also inner static classes within same outer class in which DTO class is. There classes including my DTO class are NOT annotated with any JSON annotation but only with XML annotations like @XmlRootElement and @XMLType. Should I annotate my DTO class and Class1, Class2 and Class3 with some JSON annotation like @JsonTypeName?

There is another inner class (within the same outer class) which contains a collection to the above DTO and looks like this :

@XmlRootElement(name = "dtos")
@XmlType(name = "DTOsType")
public static class DTOs{
    @JsonProperty("dtos")
    private Collection<DTO> values;

    public DTOs() {
    }

    public DTOs(final Collection<DTO> values) {
        this.values = values;
    }

    @JsonProperty("dtos")
    @XmlElement(name = "dto")
    public Collection<DTO> getValues() {
        return values;
    }
    @JsonProperty("dtos")
    public void setValues(final Collection<DTO> values) {
        this.values = values;
    }
}

obj1 and obj2 are TreeSet internally and obj3 is a TreeMap internally.

On server side my endpoint looks like this

 @POST
 @Path("{name}/endpoint")
 @Consumes({ MediaType.APPLICATION_XML, MediaType.TEXT_XML,
        MediaType.APPLICATION_JSON })
 @Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_XML,
        MediaType.TEXT_XML, MediaType.APPLICATION_JSON })
 public Response addDTO(@PathParam("name") String name, DTOs dtos) {

 //code here
 ...........
 ...........
 }

JSON input looks like the following

 {
"dtos": 
 {

"dto": 
{
    "class1s":
    {
    "class1": [
        {
           .......
        },
        {
           ........
        }
    ]},
    "name": "somename",
    "class3s": 
    {
    "class3": 
    {
        .........
    }
    },
    "id": 555589024908,

}
}

Now when I send JSON in Request Body through Postman, I get the following error

Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT 
token
at [Source: (org.apache.cxf.transport.http.AbstractHTTPDestination$1); line: 
3, column: 1] (through reference chain: my DTO class ["dto"])

I have already gone through this :

Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

I am not sure how to write a wrapper or send JSON as string to my backend REST method. The problem is with deserialisation part which is handled by framework.

This service works well with XML input.

Any pointers?

Thanks!

deepankardixit90
  • 351
  • 4
  • 19
  • your controller spect a DTO, and you send a DTOs. And you json seems invalid – cvdr Nov 16 '18 at 19:59
  • @cvdr Sorry about DTO, its DTOs actually. I have edited the question. Why do you think the JSON is wrong? – deepankardixit90 Nov 16 '18 at 21:18
  • The first thing that's wrong is that you JSON has `dtos` as an object instead of an array. That's what the exception is telling you. – Baldy Nov 16 '18 at 22:10
  • @Baldy 'dtos' is actually an inner class which has a collection of 'dto', another inner class in the main POJO. – deepankardixit90 Nov 17 '18 at 19:37
  • @raghav According to the class definition for `DTOs`, there is a JsonProperty named `dtos` as well. Since you're deserializing the class, there is no element name for the outer class so the inter property `dtos`, which is declared as a collection, needs to be an array in your JSON input. A good way to test deserialization problems is to build your objects from your classes and serialize the result to a log so you can verify that Jackson is doing what you expect. – Baldy Nov 17 '18 at 21:01
  • @Baldy I wrote some test code and reformatted the JSON input. All errors now gone but now the values are all null after deserialisation. Any idea on this? Thanks! – deepankardixit90 Nov 19 '18 at 07:28
  • Hmm, strange that serialization works but deserialization doesn't. Is it an issue with all or only certain variables? You might try writing a test program the first serializes and the deserializes the same value to see it works that way. Without looking at a full example it's pretty tough to debug. – Baldy Nov 20 '18 at 17:05
  • 1
    @Baldy Actually I found that the reason fields were not deserialised correctly was due to wrong JSON input. It had some wrapper labels and thus deserialised fields were all null. Fixed the json input and it worked as it should. Thanks! – deepankardixit90 Nov 21 '18 at 03:55

0 Answers0