Try OpenEdge Now
skip to main content
Web Services
Creating ABL Clients to Consume OpenEdge SOAP Web Services : Handling SOAP Message Headers in ABL : Creating and managing SOAP message headers : Modifying a reused SOAP response header
 
Modifying a reused SOAP response header
This example shows how you might handle a SOAP header that you first encounter in the response message returned from the Web service, then modify it as the SOAP header for the next request. The response header and its handler are identical to what is used in the header reuse example (see Reusing an unchanged SOAP response header). This is an example of the header returned from the Web service after a password is added:
SOAP request header built from a modified SOAP response header
<SOAP-ENV:Envelope
  . . .
    <SOAP-ENV:Header>
      <ns0:AuthHeader xmlns:ns0="http://ServiceHost/SOAPHeader">
        <ns0:AccessID>XYZZY</ns0:AccessID>
        <ns0:Password>Administrator</ns0:Password>
      </ns0:AuthHeader>
    </SOAP-ENV:Header>
  . . .
</SOAP-ENV:Envelope>
Note that the client adds the <Password> element as a sibling to the <AccessID> element in the existing AuthHeader header entry. Another approach is to create and add a new Password header entry as a sibling to the AuthHeader header entry itself. Again, the actual approach depends on the Web service itself, in this case the HeaderExample Web service. This type of header modification might be used when the Web service and client maintain a consistent context for each other between requests and the operation involved requires authorization or authentication or some other additional context information.
The following code is the mainline of a procedure that invokes the Web service to reuse the initial SOAP response header by adding a password node to it before passing it back as a SOAP request header:
1. Defines several mainline variables, including handles to access the global reused SOAP header (g_header) and its XML, and a variable to hold the password value (cPassword).
2. Registers the request header (ReqHandler) and response header (RespHandler) handlers after connecting to the Web service and instantiating the HeaderSoap port type procedure object.
3. Runs the OpenAccess procedure to invoke the Web service operation that returns the AccessID value in the SOAP response header (see Response header handler for returning a header for reuse).
Invoking a request that modifies a reused SOAP response header
/* SOAPHeader2.p
  An addition to SOAPHeader1.p.
  Calls a ficticious Web service. The first operation (OpenAccess) sends 
nothing in the request headers and gets back a SOAP response header
containing an AccessID. The second operation (HelloWorld) sends the AccessID 
back in its request header. (No additional information is received in the
response header.) The third operation (HelloSecureWorld) adds a Password
node to the existing AccessID entry in its request header. This Password
node is added as a sibling of the AccessID element and NOT as a new SOAP
header entry. (Once again no additional information is received in the
response header.) The Web service has only one service and port available.
*/
/*1*/
/* Define local variables */
DEFINE VARIABLE hWebSrvc      AS HANDLE.
DEFINE VARIABLE hPortType     AS HANDLE.
DEFINE VARIABLE cResponse     AS CHARACTER FORMAT "x(72)".
DEFINE VARIABLE hXdoc         AS HANDLE.
DEFINE VARIABLE hXnoderef1    AS HANDLE.
DEFINE VARIABLE hXnoderef2    AS HANDLE.
DEFINE VARIABLE hXtext        AS HANDLE.
DEFINE VARIABLE cPassword     AS CHARACTER INIT ?.
DEFINE VARIABLE g_header      AS HANDLE.

/* Create the Web service server object */
CREATE SERVER hWebSrvc.

/* Connect to the WS */
hWebSrvc:CONNECT("-WSDL
                  http://ServiceHost/SOAPHeader/HeaderExample.asmx?wsdl").

/* Get the method, set the port type */
RUN HeadersSoap SET hPortType ON hWebSrvc.
/*2*/
/* Associate the req. & resp. callbacks with the port type */
hPortType:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "ReqHandler").
hPortType:SET-CALLBACK-PROCEDURE("RESPONSE-HEADER", "RespHandler").
/*3*/
/* Invoke the Web service with no header and display the results */
RUN OpenAccess IN hPortType (OUTPUT cResponse).
DISPLAY cResponse LABEL "WS response" WITH FRAME aaa.
/*4*/
/* Go again with the AccessID set from previous response */
cResponse = "".
RUN HelloWorld IN hPortType (OUTPUT cResponse).
DISPLAY cResponse LABEL "WS response" WITH FRAME bbb.
/*5*/
/* Go again with the AccessID set from previous response */
/* header together with an added Username and Password   */
cResponse = "".
cPassword = "Administrator".
RUN HelloSecureWorld IN hPortType (OUTPUT cResponse).
DISPLAY cResponse LABEL "WS response" WITH FRAME ccc.
/*6*/
DELETE OBJECT g_header.
DELETE OBJECT hPortType.
hWebSrvc:DISCONNECT().
DELETE OBJECT hWebSrvc.

/**************** Internal Procedures ****************/
4. Runs the HelloWorld procedure to invoke the next Web service operation, passing back the SOAP response header to the Web service unchanged as the SOAP request header (see Request header handler for reusing and modifying a header).
5. Runs the HelloSecureWorld procedure to invoke the next Web service operation, passing back the password-modified SOAP response header as the Web service SOAP request header (see Request header handler for reusing and modifying a header).
Note: The header handler processing for Step 4 is different from Step 5, to reflect that the initial SOAP response header is unchanged for one request and modified for the next.
6. Cleans up the global objects maintained in its context and disconnects from the Web service. Note that one of the objects it deletes is the original SOAP response header saved by the response header handler during execution of the OpenAccess procedure.
* Request header handler for reusing and modifying a header