How to get CXF to understand the map <String, <List <MyBean>>?
My calm method returns Map<String,List<MyBean>>, but I can't figure out how to get CXF and JAXB to serialize this as XML.
I want it to look something like this (although I have not all been so worried about how it gets serialized while it works on both sides);
<response>
<items key="a">
<item>
....
</item>
<item>
....
</item>
</items>
<items key="b">
<item>
....
</item>
</items>
</response>
If I return only Map, I get:
[org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor] A message body writer was not found for the HashMap response class.
If I try to use a wrapper object, I get:
[org.apache.cxf.jaxrs.provider.AbstractJAXBProvider] java.util.List is an interface, and JAXB cannot process interfaces.
Any suggestions? Is this just a CXF problem (I'm using version 2.3.2)? I'm sure I had a similar job in Jersey.
- , . , , Map , List List.
@XmlRootElement
public class MyResponse {
private List<ItemListWrapper> items;
//getters and setters
}
@XmlType
public class ItemListWrapper {
private String key;
private List<Item> items;
@XmlAttribute
public String getKey() {
return this.key;
}
//rest of the getters and setters
}
@XmlType
public class Item {
//just a bean
}
Why not try using a specific List implementation? Or create your own marshaller who will try to figure out which list you are dealing with.
http://fusesource.com/docs/esb/4.3.1/cxf_interceptors/CXFInterceptorIntro.html
You can specify the configuration for msg-handlers / providers as follows if you are using CXF 2.3.2 with Spring:
<jaxrs:server id="restContainer" address="/">
<jaxrs:serviceBeans>
<ref bean="yourRestfulServiceBeanId"/>
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="xml" value="application/xml"/>
</jaxrs:extensionMappings>
<jaxrs:providers>
<ref bean="jaxbXmlProvider"/>
</jaxrs:providers>
</jaxrs:server>
<!-- Webservice message handlers -->
<bean id="jaxbXmlProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="jaxbElementClassMap" ref="propertiesMap"/>
</bean>
<util:map id="propertiesMap">
<entry key="jaxb.formatted.output">
<value type="java.lang.Boolean">true</value>
</entry>
</util:map>
The handler will see the JAXB annotations and generate the required output.