I am trying to add implicit headers to WSDL and WADL responses for a CXF SOAP/REST web service (which is managed by Camel).
(These are not necessarily security headers....)
By "implicit header" I mean that hitting the WSDL/WADL URL of the service will show that it's expected of the client to provide the header in the request.
But I do not want to explicitly specify the header in the signature of the web service.
I have a CXF interceptor that adds an implicit header to every SOAP/REST response.
So since WSDL/WADL document are sent as a response to some GET request, I was thinking to somehow use a similar interceptor to add the header data to WSDL/WADL response. How could I carry out such a marvellous feat?
Here is the CXF interceptor that adds an implicit header to every SOAP/REST response:
public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
public MyInterceptor()
{
super(Phase.RECEIVE);
}
@Override
public void handleMessage(Message message)
{
try
{
//soap
if (message instanceof SoapMessage)
{
List<Header> headers = ((SoapMessage)message).getHeaders();
Header dummyHeader = new Header(new QName("uri:org.apache.cxf", "dummy"), "decapitated", new JAXBDataBinding(String.class));
headers.add(dummyHeader);
}
//rest
else
{
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
String dummyHeader = "decapitated";
headers.put("dummy", Collections.singletonList(dummyHeader));
}
}
catch (JAXBException e)
{
throw new Fault(e);
}
}
@Override
public void handleFault(Message messageParam)
{
}
}
In CXF, the WSDL is generated through an Interceptor in the in chain called the WSDLGetInterceptor
, that is placed in the READ
chain.
It's basic design is
The easiest way to act on this process is to preempt this interceptor from doing its job, either by registering your own implementation before.
Removing standard CXF interceptors is kind of a "hard thing to do" on a default Bus (easiest way is to register your own interceptor, put it first in the chain, and make it remove other interceptors like so message.getInterceptorChain().remove(removeInterceptor);
But adding your own just before the standard WSDL interceptor is easy :
public MyWSDLGetInterceptor() {
super(Phase.READ);
addBefore(WSDLGetInterceptor.class.getName());
}
The MyWSDLGetInterceptor
would extend the standard WSDLGetInterceptor
and you'd only override :
public Document getDocument(Message message,
String base,
Map<String, String> params,
String ctxUri,
EndpointInfo endpointInfo) {
Document domDocument = super.getDocument(message, base, params, ctxUri, endpointInfo);
domDocument.getChildNodes(); // Whatever you need to add remove
return domDocument; // Once modified
}
You could modify the resulting DOM Document on the fly (add / create DOM nodes) or through XSLT, whatever suits you best, you're back to handling standard XML through a standard API.
The principal is the same, but the interceptor works differently.
WSDLGetOutInterceptor
in the output chain WSDLGetOutInterceptor
does its serialization jobSo it's a bit harder / less clean. But using the same principle of pre-empting the base interceptor (registering yourself just before), you could override the cleanUpOutInteceptors
to manipulate the message, just as in the 2.7.4 case, by accessing the WSDL through outMessage.get(DOCUMENT_HOLDER)
Sorry, I have no expertise, but I guess CXF has the same kind of architecture for both...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With