I am doing my services the same way, and I have a SOAP service in this
mix as well. The ONLY way that I could get this to work 100% was to
make separate class definitions for XML and JSON, and then have
translator classes to translate between the instances before being
serialized. The result was a json.XXX class that only has Xml
annotations on member lists, and the natural context then worked
wonderfully, and I didn't have to fight whether the class field was an
attribute or an element in the Xml. If you like, I can post some of my
code, but you pretty much have the same thing posted here. The only
major difference was there was no way to make the same source
annotations to work cleanly as both XML an JSON.
From: Adam Brown [mailto:adam.brown_at_mindheap.com]
Sent: Wednesday, June 17, 2009 16:58
To: users_at_jersey.dev.java.net
Subject: [Jersey] Can I make JSONConfiguration ignore @XmlElementWrapper
and @XmlElements
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.