title: Creating a JAX-RS object that contains collections and primitives as values of a map
body: <p>I have attempting to create a JAX-RS service that allows for mixed values of primitives, maps, and lists as the values for maps and lists. All attributes in the domain model cannot be specifically defined as data will be coming from different systems where some attributes will exist and others will not. The service needs to supports both XML and JSON. The JSON structure needs to be similar to as it is listed below, without extra nesting of elements due to wrapper classes. The XML structure is not set yet and is more malleable.</p>
  
  <p>I have been using Resteasy and Jackson thus far and have been shying away from vendor specific annotations however I realize that this may be unavoidable. These services APIs not locked in and I am open to other suggestions that can accomplish this goal. The one requirement is that this is a standard REST service.</p>
  
  <p>Example object that represents an article:</p>
  
  <pre><code>@XmlAccessorType(XmlAccessType.FIELD)
  @XmlRootElement
  public class Article {
  
      @XmlElement
      private String title;
  
      @XmlElement
      private String creator;
  
      @XmlElement
      private Map&lt;String, Object&gt; attributes;
  
      public Map&lt;String, Object&gt; getAttributes() {
          return attributes;
      }
  
      public void setAttributes(Map&lt;String, Object&gt; attributes) {
          this.attributes = attributes;
      }
  
      public String getTitle() {
          return title;
      }
  
      public void setTitle(String title) {
          this.title = title;
      }
  }
  </code></pre>
  
  <p>Given this object I would expect the JSON to look like:</p>
  
  <pre><code>{
      "title": "Some Title",
      "attributes":
      {
          "relevance": 0.93,
          "rating": 4,
      },
      "actions":
      [
          "A",
          "C"
      ]
  }
  </code></pre>
  
  <p>And XML to look like:</p>
  
  <pre><code>&lt;article&gt;
      &lt;title&gt;Some Title&lt;/title&gt;
      &lt;attributes&gt;
          &lt;entry&gt;
              &lt;key&gt;relevance&lt;/key&gt;
              &lt;value xsi:type="xs:double"&gt;0.93&lt;/value&gt;
          &lt;/entry&gt;
          &lt;entry&gt;
              &lt;key&gt;rating&lt;/key&gt;
              &lt;value xsi:type="xs:int"&gt;4&lt;/value&gt;
          &lt;/entry&gt;
          &lt;entry&gt;
              &lt;key&gt;actions&lt;/key&gt;
              &lt;value&gt;
                  &lt;list xsi:type="xs:string"&gt;A&lt;/list&gt;
                  &lt;list xsi:type="xs:string"&gt;C&lt;/list&gt;
            &lt;/value&gt;
          &lt;/entry&gt;
      &lt;/attributes&gt;
  &lt;/article&gt;
  </code></pre>
  
  <p>The issues I have encountered are if the value of a map is a standard ArrayList the JSON processing works fine however the XML for does not contain the information about the contents of the array. The XML looks like the following:</p>
  
  <pre><code>&lt;article&gt;
      &lt;title&gt;Some Title&lt;/title&gt;
      &lt;attributes&gt;
          &lt;entry&gt;
              &lt;key&gt;relevance&lt;/key&gt;
              &lt;value xsi:type="xs:double"&gt;0.93&lt;/value&gt;
          &lt;/entry&gt;
          &lt;entry&gt;
              &lt;key&gt;rating&lt;/key&gt;
              &lt;value xsi:type="xs:int"&gt;4&lt;/value&gt;
          &lt;/entry&gt;
          &lt;entry&gt;
              &lt;key&gt;actions&lt;/key&gt;
              &lt;value&gt;
     -----&gt;     &lt;arraylist/&gt;
            &lt;/value&gt;
          &lt;/entry&gt;
      &lt;/attributes&gt;
  &lt;/article&gt;
  </code></pre>
  
  <p>To display the contents of the list when a value of a map the list needs to be wrapped in an object that has JAXB annotations on it. However doing so adds another level to the JSON when accessing the attributes, which is undesired. If an XmlAdaptor is used to unwrap the nested object the XML again returns  for the value.</p>
  
  <p>Ideally I would want the Maps and Lists to be strongly typed so that only object wrappers that have JAXB annotations on them can be added.</p>
  
  <p>Something like the hierarchy below:</p>
  
  <p>Root class</p>
  
  <pre><code>@XmlAccessorType(XmlAccessType.NONE)
  @XmlSeeAlso({JaxbList.class, JaxbMap.class, JaxbString.class})
  abstract public class JaxbObject&lt;E&gt; {
  
      @XmlElement
      abstract public E getValue();
      abstract public void setValue(E value);
  }
  </code></pre>
  
  <p>Implementing classes</p>
  
  <pre><code>@XmlAccessorType(XmlAccessType.NONE)
  @XmlSeeAlso({JaxbObject.class})
  public class JaxbList extends JaxbObject&lt;ArrayList&lt;JaxbObject&lt;?&gt;&gt;&gt; {
  
      private ArrayList&lt;JaxbObject&lt;?&gt;&gt; value;
  
      public ArrayList&lt;JaxbObject&lt;?&gt;&gt; getValue() {
          return this.value;
      }
  
      public void setValue(ArrayList&lt;JaxbObject&lt;?&gt;&gt; value) {
          this.value = value;
      }
  }
  
  @XmlAccessorType(XmlAccessType.NONE)
  @XmlSeeAlso({JaxbObject.class})
  public class JaxbMap extends JaxbObject&lt;HashMap&lt;String, JaxbObject&lt;?&gt;&gt;&gt; {
  
      private HashMap&lt;String, JaxbObject&lt;?&gt;&gt; value;
  
      public HashMap&lt;String, JaxbObject&lt;?&gt;&gt; getValue() {
          return this.value;
      }
  
      public void setValue(HashMap&lt;String, JaxbObject&lt;?&gt;&gt; value) {
          this.value = value;
      }
  }
  
  
  @XmlAccessorType(XmlAccessType.NONE)
  @XmlType
  final public class JaxbString extends JaxbObject&lt;String&gt; {
  
      private String value;
  
      public String getValue() {
          return this.value;
      }
  
      public void setValue(String value) {
          this.value = value;
      }
  }
  
  
  @XmlAccessorType(XmlAccessType.NONE)
  @XmlType
  final public class JaxbInt extends JaxbObject&lt;Integer&gt; {
  
      private Integer value;
  
      public Integer getValue() {
          return this.value;
      }
  
      public void setValue(Integer value) {
          this.value = value;
      }
  }
  </code></pre>
  
  <p>I would expect that if getValue() could be annotated with @XmlValue then the wrapper classes would not be added to the XML or JSON however @XMLValue is not valid in that location. I did see a post about @XMLValue being valid in that location for Moxy however to move to Moxy I would need to know that what I am attempting to do is supported by it.</p>