Since 2.40, GWS supports SOAP 1.2. GWS is able to communicate with Web services provided with SOAP 1.1 or SOAP 1.2.
A GWS server can deliver a service in SOAP 1.1 or SOAP 1.2 using com.WebService.setFeature function.
For example in $FGLDIR/demo/WebServices/calculator/server/calculatorServer.4gl, the calculator server offers the service in SOAP 1.1 and SOAP 1.2.
LET serv = com.WebService.CreateWebService("Calculator",serviceNS) CALL serv.setFeature("Soap1.1",TRUE) CALL serv.setFeature("Soap1.2",TRUE)
A GWS client can consume a service in SOAP 1.1 or SOAP 1.2.
For example:
To create a client that consumes the Calculator service in SOAP 1.1 use command:
fglwsdl -soap11 -o ws_calculator http://localhost:8090/Calculator?WSDL
To create a client that consumes the Calculator service in SOAP 1.2 use command:
fglwsdl -soap12 -o ws_calculatorSoap12 http://localhost:8090/Calculator?WSDL
Be aware to generate different clients for each SOAP versions. Even if the same operations are provided, the services are using different protocols so the underlying generated stubs are also different.
Since 2.40, GWS supports SOAP fault.
For backward compatibility, fglwsdl tool provides option -ignoreFaults to disable SOAP fault management.
A GWS server can throw a SOAP fault if any processing error is encountered.
To generate a SOAP fault you need to:
For example in $FGLDIR/demo/WebServices/calculator/server/calculatorServer.4gl, the calculator server has a divide_by_zero SOAP fault. The SOAP fault is raised when you try to divide a number by zero. To generate a SOAP fault proceed as follow:
Create a SOAP fault
You define the variable to send as a SOAP fault. It can be a simple string like in this example or a complex type. Remember to assign a XMLName to the variable.
DEFINE divide_by_zero STRING ATTRIBUTES (XMLName="DividedByZero")
Then you inform the service that it can use this fault variable using function com.WebService.createFault.
LET serv = com.WebService.CreateWebService("Calculator",serviceNS) CALL serv.createFault(divide_by_zero,FALSE)
Add the SOAP fault to an operation
A SOAP fault can be used by an operation to inform the client that an error has occurred. An operation can use different SOAP faults but only one at a time.
LET op = com.WebOperation.CreateRPCStyle("divide","Divide",divide_in,divide_out) CALL op.addFault(divide_by_zero,NULL)
Here, the SOAP fault is added to the "divide" operation.
Send the SOAP fault
Set the values to the fault variable. The fault message is be sent to the client at the end of the operation processing.
LET divide_by_zero = "Cannot divide "||divide_in.a||" by zero" CALL com.WebServiceEngine.SetFaultDetail(divide_by_zero)
If a SOAP fault occurred the operation returns the SOAP fault number in the operation status. The SOAP fault number is defined in the generated stubs as a 4GL constant prefixed with the string FaultID_.
For example in $FGLDIR/demo/WebServices/calculator/client/ws_calculator.inc, Divide operation has a SOAP fault that informs the client when a number is divided by zero.
# # List of Soap fault constants CONSTANT FaultID_DividedByZero = 1 ... # VARIABLE : DividedByZero DEFINE DividedByZero STRING ATTRIBUTE(XMLName="DividedByZero",XMLNamespace="http://tempuri.org/") ... # Operation: Divide # FAULT #1: GLOBALS DividedByZero
You can test the operation status code accordingly and display the SOAP fault message.
For example in $FGLDIR/demo/WebServices/calculator/client/calculatorClient.4gl, when the divide operation status is 1, DividedByZero message is displayed.
ON ACTION divide CALL Divide(op1, op2) RETURNING wsstatus, result, remaind CASE wsstatus WHEN 0 DISPLAY BY NAME result,remaind DISPLAY "OK" TO msg WHEN FaultID_DividedByZero DISPLAY DividedByZero TO msg OTHERWISE DISPLAY wsError.description TO msg END CASE