Hi,
I have been trying to handle SOAP headers outside of functional operations,
meaning I do not use @WebParam to separate business concern from context
and/or authorization information. The header type is added to the SEI via
@XmlSeeAlso and using the jaxb binding I can set the header on the client
side (verified by looking at tcpmon requests/responses)
Client:
CalculatorService service = new CalculatorService(endpoint);
final Header header = new Header(new QName("messageHeader"),
messageHeader, new JAXBDataBinding(MessageHeader.class));
final List<Header> headers = new ArrayList<Header>();
headers.add(header);
Calculator calculator = service.getCalculatorPort();
((BindingProvider)calculator).getRequestContext().put(Header.HEADER_LIST,
headers);
On the server side the CXF server is created manually using
JaxWsServerFactoryBean and I register my interceptor implementation
ReadSOAPHeaderInInterceptor. Unfortunately, whatever approach I chose, I can
retrieve the "messageHeader" element from the message but the properties are
always null (values). Could somebody give me a hint of what I am missing ?
CXF Server creation:
final JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(serviceInterface);
svrFactory.setAddress(contextPath);
svrFactory.setServiceBean(endpoint);
// create the server and save the reference
final Server server = svrFactory.create();
// add our soap header interceptor
server.getEndpoint().getInInterceptors().add(new SAAJInInterceptor());
server.getEndpoint().getInInterceptors().add(new
ReadSOAPHeaderInInterceptor());
Interceptor impl:
public class ReadSOAPHeaderInInterceptor extends AbstractSoapInterceptor {
private final static Logger log =
LoggerFactory.getLogger(ReadSOAPHeaderInInterceptor.class);
private QName messageHeader = new QName("messageHeader");
private SAAJInInterceptor saajIn = new SAAJInInterceptor();
public ReadSOAPHeaderInInterceptor() {
super(Phase.USER_PROTOCOL);
addAfter(ReadHeadersInterceptor.class.getName());
addAfter(SAAJInInterceptor.class.getName());
}
@Override
public void handleMessage(final SoapMessage message) throws Fault {
log.info("handleMessage started");
Header header = message.getHeader(messageHeader);
if (null == header) {
throw new SoapFault("SOAP Header MessageHeader is missing", new
QName("missingMessageHeader"));
}
log.info("header object: " + header.getObject());
SOAPMessage doc = message.getContent(SOAPMessage.class);
if (doc == null) {
log.debug("SOAPMessage not set, handle with own saaj
interceptor");
saajIn.handleMessage(message);
doc = message.getContent(SOAPMessage.class);
}
SOAPHeader headers = null;
try {
headers = doc.getSOAPHeader();
} catch (SOAPException e) {
e.printStackTrace();
}
for (Iterator<SOAPElement> nodeIter = headers.getChildElements();
nodeIter.hasNext();) {
SOAPElement node = nodeIter.next();
log.info(String.format("node %s with value %s",
node.getNodeName(), node.getNodeValue()));
if ("messageHeader".equals(node.getNodeName())) {
log.info("found messageHeader node");
MessageHeader messageHeader = new MessageHeader();
for (int i = 0 ; i < node.getChildNodes().getLength(); i++)
{
SOAPElement property =
(SOAPElement)node.getChildNodes().item(i);
log.info("property: "+property.getNodeName());
if("session".equals(property.getNodeName())) {
messageHeader.setSession(property.getNodeValue());
} else if ("clientIP".equals(property.getNodeName())) {
messageHeader.setClientIP(property.getNodeValue());
} else if ("clientID".equals(property.getNodeName())) {
messageHeader.setClientID(property.getNodeValue());
} else if ("requestID".equals(property.getNodeName())) {
try {
messageHeader.setRequestID(Integer.parseInt(property.getNodeValue()));
} catch (NumberFormatException nfe) {
log.warn("requestId is not valid:
"+property.getNodeValue());
messageHeader.setRequestID(0);
}
}
}
RequestContext.getInstance().setMessageHeader(messageHeader);
break;
}
}
}
}
Thanks and Regards,
Michael