Thursday, 14 April 2016

XML : jackson List of subclasses deserialisation

I am working on a webservice where i am supposed to provide xml as response, I am using jackson for that. I am stuck at an issue, I have an abstract class:

  package com.spinner.jackson;  import java.util.ArrayList;  import java.util.List;    import com.fasterxml.jackson.annotation.JsonTypeInfo;  import com.fasterxml.jackson.annotation.JsonUnwrapped;  import com.fasterxml.jackson.annotation.JsonValue;  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;    public class ClientObject {        @JacksonXmlElementWrapper(useWrapping = false)      @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)      private List<MyItem> accounts;        public ClientObject(List<MyItem> pl) {          this.accounts = pl;      }        public ClientObject() {          this.accounts = new ArrayList<MyItem>();      }        @JsonDeserialize(using = CustomDeserial.class)      public void setL(List<MyItem> l) {          this.accounts = l;      }        public List<MyItem> getAccounts() {          // TODO Auto-generated method stub          return this.accounts;      }  }    

and then I have sub classes as follow:

package com.spinner.jackson;

  import javax.xml.bind.annotation.XmlRootElement;  import com.fasterxml.jackson.annotation.JsonCreator;  import com.fasterxml.jackson.annotation.JsonProperty;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;    @JacksonXmlRootElement(localName="itemA")  public class MySubItemA extends MyItem {        public MySubItemA() {          super();          // TODO Auto-generated constructor stub      }        public MySubItemA(int id, String name) {          super(id, name);          // TODO Auto-generated constructor stub      }        private String itemAProperty1;      private String itemAProperty2;        public String getItemAProperty1() {          return this.itemAProperty1;      }        public void setItemAProperty1(String itemAProperty1) {          this.itemAProperty1 = itemAProperty1;      }        public String getItemAProperty2() {          return this.itemAProperty2;      }        public void setItemAProperty2(String itemAProperty2) {          this.itemAProperty2 = itemAProperty2;      }        @JsonCreator      public MySubItemA(@JsonProperty("id")int id, @JsonProperty("name")String name, @JsonProperty("itemAProperty1")String p1, @JsonProperty("itemAProperty2")String p2) {          super(id, name);          this.itemAProperty1 = p1;          this.itemAProperty2 = p2;      }    }    

another sub class

  package com.spinner.jackson;    import javax.xml.bind.annotation.XmlRootElement;    import com.fasterxml.jackson.annotation.JsonProperty;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;    @JacksonXmlRootElement(localName="itemB")  public class MySubItemB extends MyItem {        private int itemBProperty1;      private String itemBProperty2;        public int getItemBProperty1() {          return this.itemBProperty1;      }        public void setItemBProperty1(int itemBProperty1) {          this.itemBProperty1 = itemBProperty1;      }        public String getItemBProperty2() {          return this.itemBProperty2;      }        public void setItemBProperty2(String itemBProperty2) {          this.itemBProperty2 = itemBProperty2;      }        public MySubItemB(@JsonProperty("id")int id, @JsonProperty("name")String name, @JsonProperty("itemBProperty1")int p1, @JsonProperty("itemBProperty2")String p2) {          super(id, name);          this.itemBProperty1 = p1;          this.itemBProperty2 = p2;      }  }    

and a client class as followed:

  package com.spinner.jackson;  import java.util.ArrayList;  import java.util.List;    import com.fasterxml.jackson.annotation.JsonTypeInfo;  import com.fasterxml.jackson.annotation.JsonUnwrapped;  import com.fasterxml.jackson.annotation.JsonValue;  import com.fasterxml.jackson.databind.annotation.JsonDeserialize;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;  import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlText;    public class ClientObject {        @JacksonXmlElementWrapper(useWrapping = false)      @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)      private List<MyItem> accounts;        public ClientObject(List<MyItem> pl) {          this.accounts = pl;      }        public ClientObject() {          this.accounts = new ArrayList<MyItem>();      }        @JsonDeserialize(using = CustomDeserial.class)      public void setL(List<MyItem> l) {          this.accounts = l;      }        @JsonDeserialize(using = CustomDeserial.class)      public List<MyItem> getAccounts() {          // TODO Auto-generated method stub          return this.accounts;      }  }    

above generate output xml as followed

  <ClientObject>      <accounts>          <MySubItemA>              ....          </MySubItemA>      </accounts>      <accounts>          <MySubItemB>              ....          </MySubItemB>      </accounts>  </ClientObject>    

is there a way to remove wrapper even though I am using @JacksonXmlElementWrapper(useWrapping = false), also if I remove this annotation it does something as followed

  <ClientObject>      <accounts>          <accounts>              <MySubItemA>                  ....              </MySubItemA>          </accounts>          <accounts>              <MySubItemB>                  .....              </MySubItemB>          </accounts>      </accounts>  </ClientObject>    

thanks for your help.

Best regards Sajid

No comments:

Post a Comment