title: RestEasy, how to prevent marshalling of JAXB annotated POJOs to and from JSON
body: <p>I started with a service that consumes and produces output in JSON. I use the <em>resteasy-jackson-provider</em> for (de)marshalling which takes its information from the class description. After a while I was asked to add XML as MediaType. So I annotated my DTOs with JAXB annotations and added the <em>resteasy-jaxb-provider</em>. As a result, I observed that the produced JSON output derives from the JAXB annotations which differs from the original format. </p>
  
  <p>I am on RestEasy Version 3.0.4. As described I use the following providers </p>
  
  <ol>
  <li><em>resteasy-jackson-provider</em></li>
  <li><em>resteasy-axb-provider</em>. </li>
  <li><em>resteasy-jettison-provider</em>, because I integrated RestEasy into Spring and this provider is a transitive dependency.</li>
  </ol>
  
  <p>I got aware of the problem when I </p>
  
  <ol>
  <li>used <code>XmlElementWrapper</code> for lists and when </li>
  <li><p>I wrote a custom <code>XmlAdapter</code> which serializes a complex data structure <code>Map&lt;String, List&lt;String&gt;&gt;</code>. Requests with XML MediaType are fine. Requests with JSON MediaType cause an exception. Jackson seems to exploit the <code>XmlAdapter</code> for further information. This was not the case before. Jackson was able to marshall the Map without the JAXB annotations. </p>
  
  <p>org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "customer" (Class x.y.z.OptionalParametersMapType), not marked as ignorable
   at [Source: org.apache.catalina.connector.CoyoteInputStream@77119553; line: 1, column: 131] (through reference chain: x.y.z.Request["optional"]->x.y.zOptionalParametersMapType["customer"]
  )
          at org.codehaus.jackson.map.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:53)
          at org.codehaus.jackson.map.deser.StdDeserializationContext.unknownFieldException(StdDeserializationContext.java:267)
          at org.codehaus.jackson.map.deser.std.StdDeserializer.reportUnknownProperty(StdDeserializer.java:673)
          at org.codehaus.jackson.map.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:659)
          at org.codehaus.jackson.map.deser.BeanDeserializer.handleUnknownProperty(BeanDeserializer.java:1365)
          at org.codehaus.jackson.map.deser.BeanDeserializer._handleUnknown(BeanDeserializer.java:725)
          at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:703)
          at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
          at org.codehaus.jackson.xc.XmlAdapterJsonDeserializer.deserialize(XmlAdapterJsonDeserializer.java:59)
          at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
          at org.codehaus.jackson.map.deser.SettableBeanProperty$FieldProperty.deserializeAndSet(SettableBeanProperty.java:579)
          at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
          at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
          at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704)
          at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315)
          at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419)</p></li>
  </ol>
  
  <p>So, how can I prevent RestEasy from using the JAXB annotations for marshalling to and from JSON?</p>
  
  <p>Here is the request class:</p>
  
  <pre><code>@XmlAccessorType(XmlAccessType.FIELD)
  @XmlRootElement(name = "domainRecommendationRequest")
  public class Request {
  
      @XmlJavaTypeAdapter(OptionalParametersXmlAdapter.class)
      private Map&lt;String, List&lt;String&gt;&gt; optional = new HashMap&lt;&gt;();
  
  }
  </code></pre>
  
  <p>Here is the XmlAdapter:</p>
  
  <pre><code>@Override
  public class OptionalParametersXmlAdapter extends XmlAdapter&lt;OptionalParametersMapType, Map&lt;String, List&lt;String&gt;&gt;&gt; {
  
      public OptionalParametersMapType marshal(Map&lt;String, List&lt;String&gt;&gt; v) throws Exception {
          OptionalParametersMapType result = new OptionalParametersMapType();
          List&lt;OptionalParameterItemType&gt; optionalParameterItemTypes = new ArrayList&lt;&gt;();
  
          Set&lt;String&gt; keySet = v.keySet();
  
          for (String parameterName : keySet) {
              OptionalParameterItemType item = new OptionalParameterItemType();
              item.name = parameterName;
              item.values = v.get(parameterName);
              optionalParameterItemTypes.add(item);
          }
  
          result.parameter = optionalParameterItemTypes;
  
          return result;
      }
  }
  </code></pre>
  
  <p>Here is the wrapper for the map:</p>
  
  <pre><code>public class OptionalParametersMapType {
      public List&lt;OptionalParameterItemType&gt; parameter = new ArrayList&lt;&gt;();
  
  }
  </code></pre>
  
  <p>Here is the actual map entry item:</p>
  
  <pre><code>public class OptionalParameterItemType {
  
      @XmlAttribute
      public String name;
  
      @XmlElementWrapper(name = "values")
      @XmlElement(name = "value")
      public List&lt;String&gt; values = new ArrayList&lt;&gt;();
  }
  </code></pre>
  
  <p>This is what I expect in the JSON request:</p>
  
  <pre><code>{"optional":{"customer":["Mike"]}}
  </code></pre>
  
  <p>As you can see, I do intend to have a different format in XML.</p>