Add a Special SOAP Header
HydraExpress offers full support for SOAP and transport headers, and processes all required headers as well as any number of custom header elements. In this section, we extend the HelloWorld example further to create an appropriate response based on a provided locale.
Add the SOAP Header to the Generated Client
The first step is to modify the generated client implementation by adding a SOAP header element to a
rwsf::CallInfo object. The call to the client proxy
sayHello() service operation method passes in the
rwsf::CallInfo object. The code that assembles the request message adds the SOAP header elements to the SOAP message header as well as adding the transport header elements to the transport header.
NOTE >> This example manipulates the SOAP header directly in the client and server implementation code, for the sake of simplicity. A better design would be to create message handlers on the client and server to do this work outside of the business logic. This design would allow future changes without having to recompile and redeploy the service. For information on creating custom message handlers, see
Chapter 14, “SOAP Message Handlers.” Open the generated client sample implementation, GreetingPortClient.cpp, located in the Extended\app\client directory.
Here’s the generated service operation method, as yet unimplemented. We’ll add the new code to this method.
void invoke_sayHello(GreetingBindingProxy& proxy)
{
std::string hellorequest_in;
std::string return_ret;
rwsf::CallInfo callInfo;
try {
return_ret = proxy.sayHello(callInfo, hellorequest_in);
} catch(const rwsf::SoapFaultException& e) {
std::cout << "Fault Code: " << e.getFault().getFaultcode().asString()
<< std::endl;
std::cout << "Fault String: " << e.getFault().getFaultstring() << std::endl;
}
}
Replace the above code for the service operation method with the following implementation to add a SOAP header element to the request message:
void invoke_sayHello(GreetingBindingProxy& proxy)
{
std::string hellorequest_in("World!");
std::string return_ret;
try {
rwsf::CallInfo callInfo; //1
callInfo.addRequestSoapHeader(rwsf::XmlName("LocaleHeader",
rwsf::XmlNamespace("locale",
"http://www.roguewave.com/examples/webservices/helloworld")),
"es_MX"); //2
return_ret = proxy.sayHello(callInfo, hellorequest_in); //3
std::cout << "Server Response: " << return_ret << std::endl;
} catch(const rwsf::SoapFaultException& e) {
std::cout << "Fault Code: " << e.getFault().getFaultcode().asString()
<< std::endl;
std::cout << "Fault String: " << e.getFault().getFaultstring() << std::endl;
}
}
Save and close the file.
Edit the Server-Side Code to Return a Response Based on the Header
On the server-side, the server code extracts the locale information from the SOAP header and uses it to create an appropriate response for the locale.
Open the generated server sample implementation GreetingPortTypeImp.cpp located in your Extended\app\server directory. Let’s look at the generated sample service operation method:
std::string
GreetingPortTypeImp::sayHello(rwsf::CallInfo& callInfo, const std::string&
hellorequest_in)
{
typedef std::string returnType;
throw rwsf::ServerFault("Sorry: The service was invoked but the requested
operation \"sayHello\" has not been implemented. An implementation must be
written.");
return returnType(); // (never executed)
}
To implement the method to extract the locale information from the client’s SOAP header, replace the code above with the implementation below:
std::string GreetingPortTypeImp::sayHello(rwsf::CallInfo& callInfo,
const std::string& hellorequest_in)
{
std::string localeValue = //1
callInfo.getRequestSoapHeaderValue(
rwsf::XmlName("LocaleHeader", rwsf::XmlNamespace("locale",
"http://www.roguewave.com/examples/webservices/helloworld")));
std::string response;
if (localeValue == "es_MX") { //2
response = "Hola al mundo!";
}
else {
response = "Hello" + hellorequest_in;
}
return std::string(response); //3
}
Save and close the file.