This article will talk about how to add soap headers in response soap message, not work around solution mentioned in previous article.
The approach is to use module/handler to inject the soap headers while responding to consumers.
follow this article Develop Web Service With Axis2 #4 - Axis2 Style Interceptor to create a new module.
------ module class
package mypackage;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.description.AxisDescription;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.modules.Module;
import org.apache.neethi.Assertion;
import org.apache.neethi.Policy;
public class SoapHeaderModule implements Module {
public void init(ConfigurationContext configurationContext,
AxisModule axisModule) throws AxisFault {
System.out.println("Initializing the module");
}
public void engageNotify(AxisDescription axisDescription) throws AxisFault {
}
public boolean canSupportAssertion(Assertion assertion) {
return false;
}
public void applyPolicy(Policy policy, AxisDescription axisDescription)
throws AxisFault {
}
public void shutdown(ConfigurationContext configurationContext)
throws AxisFault {
}
}
-------- handler class
package mypackage;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.handlers.AbstractHandler;
public class HeaderOutHandler extends AbstractHandler {
public InvocationResponse invoke(MessageContext messageContext)
throws AxisFault {
// add an Soap header for the outgoing soap message
SOAPEnvelope soapEnvelope = messageContext.getEnvelope();
if (soapEnvelope.getHeader() == null) {
String soapNamespace = soapEnvelope.getNamespace()
.getNamespaceURI();
// creating a soap factory according the the soap namespce uri
SOAPFactory soapFactory = null;
if (soapNamespace
.equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
soapFactory = OMAbstractFactory.getSOAP11Factory();
} else if (soapNamespace
.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
soapFactory = OMAbstractFactory.getSOAP12Factory();
} else {
System.out.println("Unknow soap message");
}
soapFactory.createSOAPHeader(soapEnvelope);
}
OMNamespace omNamespace = OMAbstractFactory.getOMFactory()
.createOMNamespace("http://mycompany.com", "myNs");
SOAPHeaderBlock soapHeaderBlock = soapEnvelope.getHeader()
.addHeaderBlock("responseId", omNamespace);
soapHeaderBlock.setText("11223344");
soapHeaderBlock = soapEnvelope.getHeader().addHeaderBlock(
"resonseTime", omNamespace);
soapHeaderBlock.setText(new java.util.Date().toString());
return InvocationResponse.CONTINUE;
}
}
-------------------- module configuration file
<module name="CustHeaderModule" class="mypackage.SoapHeaderModule">
<OutFlow>
<handler name="OutFlowHeaderOutHandler" class="mypackage.HeaderOutHandler">
<order phase="CustHeaderPhase" />
</handler>
</OutFlow>
</module>
---------------- modify axis2.xml
<phaseOrder type="OutFlow">
<!-- user can add his own phases to this area -->
<phase name="soapmonitorPhase"/>
<phase name="OperationOutPhase"/>
<phase name="CustHeaderPhase"/>
<phase name="auditLogPhase"/>
<!--system predefined phase-->
<!--these phase will run irrespective of the service-->
<phase name="RMPhase"/>
<phase name="PolicyDetermination"/>
<phase name="MessageOut"/>
<phase name="Security"/>
</phaseOrder>
Take note that I put CustHeaderPhase before auditLogPhase, so that inject soap headers first, auditLogPhase show response soap message including soap headers subsequently.
------------- add the module to services.xml
<module ref="auditLogger"/>
<module ref="CustHeaderModule"/>
-------- test it.
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header>
<myNs:responseId xmlns:myNs="http://mycompany.com">11223344</myNs:responseId>
<myNs:resonseTime xmlns:myNs="http://mycompany.com">Tue Jan 04 17:13:16 CST 2011</myNs:resonseTime>
</soapenv:Header>
<soapenv:Body>
<ns2:getUserProfileResponse xmlns:ns2="http://axis.test.com/ws">
<ns2:userProfileResponse>
<<ns1:age xmlns:ns1="http://bean.axis.test.com/xsd">32</ns1:age>
<ns1:userName xmlns:ns1="http://bean.axis.test.com/xsd">dddddddddd</ns1:userName>
</ns2:userProfileResponse>
</soapenv:Body>
</soapenv:Envelope>
============= Reminder ===============
to customize HTTP header is another useful function. refer to
http://www.keith-chapman.org/2008/10/axis2-setting-custom-http-headers-on.html
Example code:
MessageContext responseMessageContext = MessageContext.getCurrentMessageContext().getOperationContext().getMessageContext( WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
List headers = new ArrayList(); headers.add(new Header(HTTPConstants.HEADER_CONTENT_ENCODING, "identity")); responseMessageContext.setProperty(HTTPConstants.HTTP_HEADERS, headers);