Develop Web Service With Axis2 #7 - Add Custom Soap Header in Response Soap Message

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);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章