38.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 JAXB 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. The Holder object used here must be exactly the Holder object for the corresponding parameter that was extracted from the request Object[] array. Creating and inserting a new Holder object into the Object[] array does not work.
OUT
Contains a Holder object, which you must initialize with a response value. The Holder object used here must be exactly the Holder object for the corresponding parameter that was extracted from the request Object[] array. Creating and inserting a new Holder object into the Object[] 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});
    }

}