Reputation: 389
I am developing web services using Apache CXF and Spring. My interfaces and configuration are configured so that I have both REST and SOAP services.
Apache CXF is not putting the XML document start: <?xml version="1.0" encoding="UTF-8"?>
For the SOAP service I implemented an interceptor and it works perfectly. Here's the code:
public class CustomHeaderInterceptor extends AbstractPhaseInterceptor<Message> {
public CustomHeaderInterceptor() {
super(Phase.PRE_STREAM);
addBefore(StaxOutInterceptor.class.getName());
}
@Override
public void handleMessage(Message message) throws Fault {
message.put(Message.ENCODING, "UTF-8");
message.put(StaxOutInterceptor.FORCE_START_DOCUMENT, Boolean.TRUE);
}
}
The interceptor is added with the following configuration:
<bean id="customHeader" class="com.minervanetworks.xtv.stb.utils.CustomHeaderInterceptor" />
<cxf:bus>
<cxf:inInterceptors>
<ref bean="logInbound" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="customHeader" />
<ref bean="logOutbound" />
</cxf:outInterceptors>
<cxf:inFaultInterceptors>
<ref bean="logInbound" />
</cxf:inFaultInterceptors>
<cxf:outFaultInterceptors>
<ref bean="logOutbound" />
</cxf:outFaultInterceptors>
</cxf:bus>
Unfortunately this does not work for my JAX-RS server. The "StaxOutInterceptor.FORCE_START_DOCUMENT" is processed by the StaxOutInterceptor and it is not in the chain when I'm using JAX-RS. It could not be added manually since it depends on StaxOutEndingInterceptor which is in the *ending phase and is called after JAXRSOutInterceptor.
I also tried implementing handler for the same purpose but without any success.
Here is my JAXRS server configuration:
<jaxrs:server id="restServer" address="/rest">
<jaxrs:providers>
<ref bean="systemExceptionMapper" />
<ref bean="jaxbProvider" />
</jaxrs:providers>
<jaxrs:serviceBeans>
...
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="feed" value="application/atom+xml" />
<entry key="html" value="text/html" />
</jaxrs:extensionMappings>
</jaxrs:server>
Any kind of help - ideas, suggestions, whatever will be appriciated!
Upvotes: 2
Views: 1144
Reputation: 389
After lots of time invested in this problem, I found the following solution.
Apache CXF is not putting the XML Document Start when it is marshaling collections, which was my case. It is kind of omission in JAXBElement provider. I realized that everything is just fine when marshaling single objects.
So the obvious solution for me was to wrap my collection in a collection object, like this:
public class CollectionWrapper{
private List collection;
...
}
Refactoring my methods to return CollectionWrapper, rather than List did the job.
Upvotes: 3