Server handlers
The COM library allows you to intercept high-level Web services operation on the server side. You can now define three BDL functions via the following methods of the Web service class. They will be executed at different steps of a web service request processing in order to modify the SOAP request, response or the generated WSDL document before or after the SOAP engine has processed it. This helps handle WS-* specifications not supported in the web service API.
- Method
registerWSDLHandler()
- Method
registerInputRequestHandler()
- Method
registerOutputRequestHandler()
FUNCTION CallbackHandler( doc xml.DomDocument )
RETURNING xml.DomDocument
Example 1: Modify the generation of a WSDL
CALL serv.registerWsdlHandler("WSDLHandler")
com.WebService
and WSDLHandler
is the
following
function:FUNCTION WSDLHandler(wsdl)
DEFINE wsdl Xml.DomDocument
DEFINE node Xml.DomNode
DEFINE list Xml.DomNodeList
DEFINE ind INTEGER
DEFINE name STRING
# Add a comment
LET node = wsdl.createComment(
"First modified WSDL via a BDL callback function")
CALL wsdl.prependDocumentNode(node)
# Rename input and output parameter in UPPERCASE
LET list = wsdl.selectByXPath(
"//wsdl:definitions/wsdl:types/xsd:schema/
xsd:complexType/xsd:sequence/xsd:element/xsd:complexType/
xsd:sequence/xsd:element",NULL)
-- first input parameter for selectByXPath above
-- one string, no spaces!
FOR ind=1 TO list.getCount()
LET node = list.getItem(ind)
LET name = node.getAttribute("name")
LET name = name.toUpperCase()
CALL node.setAttribute("name",name)
END FOR
RETURN wsdl
END FUNCTION
If NULL is returned from the callback function, an HTTP error will be sent and the ProcessServices() returns error code -20.
Example 2: Change the SOAP incoming request
CALL serv.registerInputRequestHandler("InputRequestHandler")
com.WebService
and InputRequestHandler
is this
function:FUNCTION InputRequestHandler(in)
DEFINE in Xml.DomDocument
DEFINE ind INTEGER
DEFINE node Xml.DomNode
DEFINE copy Xml.DomNode
DEFINE tmp Xml.DomNode
DEFINE parent Xml.DomNode
DEFINE name STRING
DEFINE list Xml.DomNodeList
# Change input parameter below myrecord in lower case
# to follow high-level web service
LET list = in.SelectByXPath(
"//SOAP:Envelope/SOAP:Body/fjs:EchoDOCRecordRequest/fjs:myrecord/*",
"SOAP","http://schemas.xmlsoap.org/soap/envelope/",
"fjs","http://www.mycompany.com/webservices")
FOR ind = 1 TO list.getCount()
LET node = list.getItem(ind)
LET parent = node.getParentNode()
LET name = node.getLocalName()
LET copy = in.createElementNS(node.getPrefix(),
name.toLowerCase(),node.getNamespaceURI())
LET tmp = node.getFirstChild()
LET tmp = tmp.clone(true)
CALL copy.appendChild(tmp)
CALL parent.replaceChild(copy,node)
END FOR
RETURN in
END FUNCTION
If NULL is return from the callback function, a SOAP fault will be sent (but can be changed from the output handler) and the ProcessServices() returns error code -18.
Example 3: Modify the SOAP outgoing request
CALL serv.registerOutputRequestHandler("OutputRequestHandler")
com.WebService
and OutputRequestHandler
is this
function:FUNCTION OutputRequestHandler(out)
DEFINE out Xml.DomDocument
DEFINE ind INTEGER
DEFINE node Xml.DomNode
DEFINE copy Xml.DomNode
DEFINE tmp Xml.DomNode
DEFINE parent Xml.DomNode
DEFINE name STRING
DEFINE list Xml.DomNodeList
# Change output parameter below myrecord in uppercase
# before sending back to the client
LET list = out.SelectByXPath(
"//SOAP:Envelope/SOAP:Body/fjs:EchoDOCRecordResponse/fjs:myrecord/*",
"SOAP","http://schemas.xmlsoap.org/soap/envelope/",
"fjs","http://www.mycompany.com/webservices")
FOR ind = 1 TO list.getCount()
LET node = list.getItem(ind)
LET parent = node.getParentNode()
LET name = node.getLocalName()
LET copy = out.createElementNS(node.getPrefix(),name.toUpperCase(),
node.getNamespaceURI())
LET tmp = node.getFirstChild()
LET tmp = tmp.clone(true)
CALL copy.appendChild(tmp)
CALL parent.replaceChild(copy,node)
END FOR
RETURN out
END FUNCTION
If NULL is return from the callback function, a SOAP fault will be sent and the ProcessServices() returns error code -19.