35.5. Process Operation Parameters
Overview
The most important characteristic of using Camel CXF in POJO mode is that the exchange's message body contains a list of Java objects, representing the parameters of the WSDL operation. The types of the Java objects are defined by the standard JAX-B mapping and the implementations of these parameter types are provided by the Java stub code.
Contents of request message body
In POJO mode, the body of the request message is an
org.apache.cxf.message.MessageContentsList
object. You can also obtain the message body as an Object[]
array (where type conversion is automatic).
When the body is obtained as an
Object[]
array, the array contains the list of all the operation's IN, INOUT, and OUT parameters in exactly the same order as defined in the WSDL contract (and in the same order as the corresponding operation signature of the SEI). The parameter mode affects the content as follows:
IN
- Contains a parameter value from the client.
INOUT
- Contains a
Holder
object containing a parameter value from the client. OUT
- Contains an empty
Holder
object, which is a placeholder for the response.
Note
Unlike OUT parameters, there is no placeholder in the request's
Object[]
array to represent a return value.
Contents of response message body
In POJO mode, the body of the response message can be either an
org.apache.cxf.message.MessageContentsList
object or an Object[]
array.
When setting the response body as an
Object[]
array, the array should contain only the operation's INOUT and OUT parameters in the same order as defined in the WSDL contract, omitting the IN parameters. The parameter mode affects the content as follows:
INOUT
- Contains a
Holder
object, which you must set to a response value. TheHolder
object used here must be exactly theHolder
object for the corresponding parameter that was extracted from the requestObject[]
array. Creating and inserting a newHolder
object into theObject[]
array does not work. OUT
- Contains a
Holder
object, which you must initialize with a response value. TheHolder
object used here must be exactly theHolder
object for the corresponding parameter that was extracted from the requestObject[]
array. Creating and inserting a newHolder
object into theObject[]
array does not work.
Note
If you defined the Web service interface using the Java-first approach, note that the return value (if any) must be set as the first element in the response's
Object[]
array. The return type is set as a plain object: it does not use a Holder
object.
Example: getCustomerStatus operation
For example, the
getCustomerStatus
operation takes three parameters: IN, OUT, and OUT, respectively. The corresponding method signature in the SEI is, as follows:
// Java public void getCustomerStatus( @WebParam(name = "customerId", targetNamespace = "") java.lang.String customerId, @WebParam(mode = WebParam.Mode.OUT, name = "status", targetNamespace = "") javax.xml.ws.Holder<java.lang.String> status, @WebParam(mode = WebParam.Mode.OUT, name = "statusMessage", targetNamespace = "") javax.xml.ws.Holder<java.lang.String> statusMessage );
Example: request and response bodies
For the
getCustomerStatus
operation, the bodies of the request message and the response message have the following contents:
- Request message—as an
Object[]
array type, the contents are:{ String customerId, Holder<String> status, Holder<String> statusMessage }
. - Response message—as an
Object[]
array type, the contents are:{Holder<String> status, Holder<String> statusMessage }
Example: processing getCustomerStatus
The
GetCustomerStatusProcessor
class is responsible for processing incoming getCustomerStatus
invocations. The following sample implementation for POJO mode shows how to read the request parameters from the In message body and then set the response parameters in the Out message body.
// Java package com.fusesource.customerwscamelcxfpojo; import javax.xml.ws.Holder; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class GetCustomerStatusProcessor implements Processor { public static final Logger log = LoggerFactory.getLogger(GetCustomerStatusProcessor.class); public void process(Exchange exchng) throws Exception { Object[] args = exchng.getIn().getBody(Object[].class); String id = (String) args[0]; Holder<String> status = (Holder<String>) args[1]; Holder<String> statusMsg = (Holder<String>) args[2]; log.debug("Getting status for customer '" + id + "'"); // This is where you'd actually do the work! Setting // the holder values to constants for the sake of brevity. // status.value = "Offline"; statusMsg.value = "Going to sleep now!"; exchng.getOut().setBody(new Object[] {status , statusMsg}); } }