users@jersey.java.net

Can I make JSONConfiguration ignore _at_XmlElementWrapper and @XmlElements

From: Adam Brown <adam.brown_at_mindheap.com>
Date: Wed, 17 Jun 2009 15:58:26 -0700

I have a resource that produces application/json and application/xml output.
The response bean contains a property called params.

  public List<SearchResponseParam> getParams() {
    return params;
  }

  public void setParams(List<SearchResponseParam> params) {
    this.params = params;
  }

It is very easy to make this come out nicely in json using the following:

@Provider
public class JsonFormatJaxbContextResolver implements
ContextResolver<JAXBContext> {

  private JAXBContext context;
  private Class[] types = {
      SearchResponse.class,
      SearchResponseFacetField.class,
      SearchResponseFacetValueFilter.class,
      SearchResponseFacetValueGroupFilter.class,
      SearchResponseParam.class,
      SearchResponseQuery.class,
      SearchResponseRangeFacetField.class,
      SearchResponseRangeFilter.class,
      SearchResponseSearchTerm.class,
      SearchResponseSortField.class,
      SearchResponseTextFilter.class,
      SearchResponseTextQuery.class
  };

  public JsonFormatJaxbContextResolver() throws Exception {
    this.context = new JSONJAXBContext(JSONConfiguration.natural().build(),
types);
  }

  public JAXBContext getContext(Class<?> objectType) {
    return (types[0].equals(objectType)) ? context : null;
  }
}

json looks like this:

"params" : [
    {
        "key" : "fullTextOnly",
        "removeCommand":"removeParameter(fullTextOnly)",
        "value":"true"
    },
    {
        "key" : "holdingsOnly",
        "removeCommand":"removeParameter(holdingsOnly)",
        "value":"false"
    }
]

However the xml comes out wrong and needs more JAXB annotations. By default
it looks like this:

<params>
    <key>fullTextOnly</key>
    <removeCommand>removeParameter(fullTextOnly)</removeCommand>
    <value>true</value>
</params>
<params>
    <key>holdingsOnly</key>
    <removeCommand>removeParameter(holdingsOnly)</removeCommand>
    <value>false</value>
</params>

I want it to look like this:

<params>
    <param key="fullTextOnly" removeCommand="removeParameter(fullTextOnly)"
value="true"/>
    <param key="holdingsOnly" removeCommand="removeParameter(holdingsOnly)"
value="false"/>
</params>

So no problem, I add a couple @XmlAttribute annotations and the following:

  @XmlElementWrapper(name="params")
  @XmlElements(@XmlElement(name="param"))
  public List<SearchResponseParam> getParams() {
    return params;
  }

and the xml comes out perfect, but now the json is broken. It appears that
the JSONConfiguration I am using ignores @XmlAttribute annotations but the
@XmlElementWrapper and @XmlElements annotations add an unwanted extra level
of wrapping. It ends up looking like this:

"params" : [
    {
        "param" : {
            "key":"fullTextOnly",
            "removeCommand":"removeParameter(fullTextOnly)",
            "value":"true"
        },
        "param" : {
            "key":"holdingsOnly",
            "removeCommand":"removeParameter(holdingsOnly)",
            "value":"false"
        }
    }
]

Is it possible to overcome this somehow. Possibly, configuring the
JSONConfiguration to ignore @XmlElementWrapper and @XmlElements somehow? It
would be nice to be able to configure a single bean that can be returned as
nicely formatted xml or json.