You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2002/10/02 22:39:07 UTC

cvs commit: xml-axis/java/src/org/apache/axis/providers/java RPCProvider.java

scheu       2002/10/02 13:39:07

  Modified:    java/src/org/apache/axis/client Tag: explicitHeaderWork
                        Call.java
               java/src/org/apache/axis/deployment/wsdd Tag:
                        explicitHeaderWork WSDDConstants.java
                        WSDDOperation.java WSDDParameter.java
               java/src/org/apache/axis/description Tag: explicitHeaderWork
                        ParameterDesc.java
               java/src/org/apache/axis/i18n Tag: explicitHeaderWork
                        resource.properties
               java/src/org/apache/axis/message Tag: explicitHeaderWork
                        RPCElement.java RPCHandler.java
               java/src/org/apache/axis/providers/java Tag:
                        explicitHeaderWork RPCProvider.java
  Added:       java/src/org/apache/axis/message Tag: explicitHeaderWork
                        RPCHeaderParam.java
  Log:
  Summary of changes
     * WSDD changes to support inHeader, outHeader, returnHeader attributes.
     * RPCElement, RPCHandler changes to deserialize header params/response as necessary.
     * RPCPRovider (and new RPCHeaderParam) changes to serialize response in header.
     * Call change to serialize using RPCHeaderParam.
     * RPCHeaderParam extends SOAPHeaderElement and wraps an RPCParam.  The outputImpl
       method is redefined to serialize using RPCParam.serialize().
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.180.4.2 +20 -22    xml-axis/java/src/org/apache/axis/client/Call.java
  
  Index: Call.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/client/Call.java,v
  retrieving revision 1.180.4.1
  retrieving revision 1.180.4.2
  diff -u -r1.180.4.1 -r1.180.4.2
  --- Call.java	2 Oct 2002 19:32:48 -0000	1.180.4.1
  +++ Call.java	2 Oct 2002 20:39:05 -0000	1.180.4.2
  @@ -77,6 +77,7 @@
   import org.apache.axis.encoding.ser.BaseSerializerFactory;
   import org.apache.axis.handlers.soap.SOAPService;
   import org.apache.axis.message.RPCElement;
  +import org.apache.axis.message.RPCHeaderParam;
   import org.apache.axis.message.RPCParam;
   import org.apache.axis.message.SOAPBodyElement;
   import org.apache.axis.message.SOAPEnvelope;
  @@ -1546,30 +1547,27 @@
               ParameterDesc param = (ParameterDesc)parameters.get(i);
               if (param.getMode() != ParameterDesc.OUT) {
                   QName paramQName = param.getQName();
  -                if (param.isInHeader()) {
   
  -                    // Add this parameter as a header.
  -                    SOAPHeaderElement header = new SOAPHeaderElement(
  -                            paramQName.getNamespaceURI(),
  -                            paramQName.getLocalPart(),
  -                            params[j++]);
  -                    addHeader(header);
  +                // Create an RPCParam if param isn't already an RPCParam.
  +                RPCParam rpcParam = null;
  +                Object p = params[j++];
  +                if(p instanceof RPCParam) {
  +                    rpcParam = (RPCParam)p;
  +                } else {
  +                    rpcParam = new RPCParam(paramQName.getNamespaceURI(),
  +                                            paramQName.getLocalPart(),
  +                                            p);
                   }
  -                else {
  -                    // Since this parameter isn't a header, keep it in the args list.
  -                    RPCParam rpcParam = null;
  -                    Object p = params[j++];
  -                    if(p instanceof RPCParam) {
  -                        rpcParam = (RPCParam)p;
  -                    } else {
  -                        rpcParam = new RPCParam(paramQName.getNamespaceURI(),
  -                                                paramQName.getLocalPart(),
  -                                                p);
  -                    }
  -                    // Attach the ParameterDescription to the RPCParam
  -                    // so that the serializer can use the (javaType, xmlType)
  -                    // information.
  -                    rpcParam.setParamDesc(param);
  +                // Attach the ParameterDescription to the RPCParam
  +                // so that the serializer can use the (javaType, xmlType)
  +                // information.
  +                rpcParam.setParamDesc(param);
  +                
  +                // Add the param to the header or vector depending
  +                // on whether it belongs in the header or body.
  +                if (param.isInHeader()) {
  +                    addHeader(new RPCHeaderParam(rpcParam));
  +                } else {
                       result.add(rpcParam);
                   }
               }
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.23.6.1  +3 -0      xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDConstants.java
  
  Index: WSDDConstants.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDConstants.java,v
  retrieving revision 1.23
  retrieving revision 1.23.6.1
  diff -u -r1.23 -r1.23.6.1
  --- WSDDConstants.java	4 Sep 2002 13:25:03 -0000	1.23
  +++ WSDDConstants.java	2 Oct 2002 20:39:06 -0000	1.23.6.1
  @@ -166,6 +166,9 @@
       public static final String ATTR_RETQNAME = "returnQName";
       public static final String ATTR_RETTYPE = "returnType";
       public static final String ATTR_MODE = "mode";
  +    public static final String ATTR_INHEADER = "inHeader";
  +    public static final String ATTR_OUTHEADER = "outHeader";
  +    public static final String ATTR_RETHEADER = "returnHeader";
       public static final String ATTR_STYLE = "style";
       public static final String ATTR_STREAMING = "streaming";
       public static final String ATTR_ATTACHMENT_FORMAT = "attachment";
  
  
  
  1.21.12.1 +10 -0     xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDOperation.java
  
  Index: WSDDOperation.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDOperation.java,v
  retrieving revision 1.21
  retrieving revision 1.21.12.1
  diff -u -r1.21 -r1.21.12.1
  --- WSDDOperation.java	26 Jun 2002 18:19:07 -0000	1.21
  +++ WSDDOperation.java	2 Oct 2002 20:39:06 -0000	1.21.12.1
  @@ -58,6 +58,7 @@
   import org.apache.axis.description.ParameterDesc;
   import org.apache.axis.description.ServiceDesc;
   import org.apache.axis.encoding.SerializationContext;
  +import org.apache.axis.utils.JavaUtils;
   import org.apache.axis.utils.XMLUtils;
   import org.w3c.dom.Element;
   import org.xml.sax.helpers.AttributesImpl;
  @@ -116,6 +117,11 @@
           if (retTypeStr != null && !retTypeStr.equals(""))
               desc.setReturnType(XMLUtils.getQNameFromString(retTypeStr, e));
   
  +        String retHStr = e.getAttribute(ATTR_RETHEADER);
  +        if (retHStr != null) {
  +            desc.setReturnHeader(JavaUtils.isTrueExplicitly(retHStr));
  +        }
  +
           Element [] parameters = getChildElements(e, ELEM_WSDD_PARAM);
           for (int i = 0; i < parameters.length; i++) {
               Element paramEl = parameters[i];
  @@ -141,6 +147,10 @@
               attrs.addAttribute("", ATTR_RETTYPE, ATTR_RETTYPE,
                                  "CDATA",
                                  context.qName2String(desc.getReturnType()));
  +        }
  +        if (desc.isReturnHeader()) {
  +            attrs.addAttribute("", ATTR_RETHEADER, ATTR_RETHEADER,
  +                               "CDATA", "true");
           }
   
           if (desc.getName() != null) {
  
  
  
  1.13.12.1 +20 -0     xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDParameter.java
  
  Index: WSDDParameter.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/deployment/wsdd/WSDDParameter.java,v
  retrieving revision 1.13
  retrieving revision 1.13.12.1
  diff -u -r1.13 -r1.13.12.1
  --- WSDDParameter.java	26 Jun 2002 18:19:07 -0000	1.13
  +++ WSDDParameter.java	2 Oct 2002 20:39:06 -0000	1.13.12.1
  @@ -58,6 +58,7 @@
   import org.apache.axis.description.ParameterDesc;
   import org.apache.axis.encoding.SerializationContext;
   import org.apache.axis.utils.XMLUtils;
  +import org.apache.axis.utils.JavaUtils;
   import org.w3c.dom.Element;
   import org.xml.sax.helpers.AttributesImpl;
   
  @@ -91,6 +92,15 @@
           if (modeStr != null && !modeStr.equals("")) {
               parameter.setMode(ParameterDesc.modeFromString(modeStr));
           }
  +
  +        String inHStr = e.getAttribute(ATTR_INHEADER);
  +        if (inHStr != null) {
  +            parameter.setInHeader(JavaUtils.isTrueExplicitly(inHStr));
  +        }
  +        String outHStr = e.getAttribute(ATTR_OUTHEADER);
  +        if (outHStr != null) {
  +            parameter.setOutHeader(JavaUtils.isTrueExplicitly(outHStr));
  +        }
           
           String typeStr = e.getAttribute(ATTR_TYPE);
           if (typeStr != null && !typeStr.equals("")) {
  @@ -130,6 +140,16 @@
           if (mode != ParameterDesc.IN) {
               String modeStr = ParameterDesc.getModeAsString(mode);
               attrs.addAttribute("", ATTR_MODE, ATTR_MODE, "CDATA", modeStr);
  +        }
  +
  +        if (parameter.isInHeader()) {
  +            attrs.addAttribute("", ATTR_INHEADER, ATTR_INHEADER,
  +                               "CDATA", "true");
  +        }
  +
  +        if (parameter.isOutHeader()) {
  +            attrs.addAttribute("", ATTR_OUTHEADER, ATTR_OUTHEADER,
  +                               "CDATA", "true");
           }
           
           QName typeQName = parameter.getTypeQName();
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.22.6.3  +20 -17    xml-axis/java/src/org/apache/axis/description/ParameterDesc.java
  
  Index: ParameterDesc.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/description/ParameterDesc.java,v
  retrieving revision 1.22.6.2
  retrieving revision 1.22.6.3
  diff -u -r1.22.6.2 -r1.22.6.3
  --- ParameterDesc.java	2 Oct 2002 20:09:00 -0000	1.22.6.2
  +++ ParameterDesc.java	2 Oct 2002 20:39:06 -0000	1.22.6.3
  @@ -86,7 +86,7 @@
       /** A TypeEntry corresponding to this parameter */
       public TypeEntry typeEntry;
       /** The Parameter mode (in, out, inout) */
  -    public byte mode = IN;
  +    private byte mode = IN;
       /** The XML type of this parameter */
       private QName typeQName;
       /** The Java type of this parameter */
  @@ -100,7 +100,7 @@
   
       /** Indicates whether input/output values are stored in the header */
       private boolean inHeader = false;
  -    private boolean outHeader = false;
  +    private boolean outHeader = false; 
   
       public ParameterDesc() {
       }
  @@ -166,6 +166,8 @@
           text+=indent + "isReturn:   " + isReturn + "\n";
           text+=indent + "typeQName:  " + typeQName + "\n";
           text+=indent + "javaType:   " + javaType + "\n";
  +        text+=indent + "inHeader:   " + inHeader + "\n";
  +        text+=indent + "outHeader:  " + outHeader+ "\n";
           return text;
       } // toString
       
  @@ -275,21 +277,6 @@
           this.order = order;
       }
   
  -    /**
  -     * Indicates ParameterDesc represents return of OperationDesc
  -     * @return true if return parameter of OperationDesc
  -     */
  -    public boolean getIsReturn() {
  -        return isReturn;
  -    }
  -    /**
  -     * Set to true to indicate return parameter of OperationDesc
  -     * @param value boolean that indicates if return parameter of OperationDesc
  -     */
  -    public void setIsReturn(boolean value) {
  -        isReturn = value;
  -    }
  -
       public void setInHeader(boolean value) {
           this.inHeader = value;
       }
  @@ -306,6 +293,21 @@
           return this.outHeader;
       }
   
  +    /**
  +     * Indicates ParameterDesc represents return of OperationDesc
  +     * @return true if return parameter of OperationDesc
  +     */
  +    public boolean getIsReturn() {
  +        return isReturn;
  +    }
  +    /**
  +     * Set to true to indicate return parameter of OperationDesc
  +     * @param value boolean that indicates if return parameter of OperationDesc
  +     */
  +    public void setIsReturn(boolean value) {
  +        isReturn = value;
  +    }
  +
       private void writeObject(ObjectOutputStream out)
           throws IOException {
           if (name == null) {
  @@ -341,4 +343,5 @@
           }
           in.defaultReadObject();
       }
  +
   } // class ParameterDesc
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.9.4.1   +1 -0      xml-axis/java/src/org/apache/axis/i18n/resource.properties
  
  Index: resource.properties
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/i18n/resource.properties,v
  retrieving revision 1.9
  retrieving revision 1.9.4.1
  diff -u -r1.9 -r1.9.4.1
  --- resource.properties	26 Sep 2002 20:32:55 -0000	1.9
  +++ resource.properties	2 Oct 2002 20:39:06 -0000	1.9.4.1
  @@ -1031,3 +1031,4 @@
   unmatchedOp=Binding operation has no corresponding portType operation:  name = {0}, input name = {1}, output name = {2}
   noOperationForQName=Couldn't find an appropriate operation for XML QName {0}
   noParmDesc=operation description is missing parameter description!
  +expectedHeaderParam=Found instance data for {0} in the soap:body instead of the soap:header.
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.76.4.1  +139 -0    xml-axis/java/src/org/apache/axis/message/RPCElement.java
  
  Index: RPCElement.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCElement.java,v
  retrieving revision 1.76
  retrieving revision 1.76.4.1
  diff -u -r1.76 -r1.76.4.1
  --- RPCElement.java	29 Sep 2002 19:35:52 -0000	1.76
  +++ RPCElement.java	2 Oct 2002 20:39:06 -0000	1.76.4.1
  @@ -59,6 +59,7 @@
   import org.apache.axis.Message;
   import org.apache.axis.MessageContext;
   import org.apache.axis.description.OperationDesc;
  +import org.apache.axis.description.ParameterDesc;
   import org.apache.axis.description.ServiceDesc;
   import org.apache.axis.encoding.DeserializationContext;
   import org.apache.axis.encoding.SerializationContext;
  @@ -68,6 +69,9 @@
   import org.apache.axis.wsdl.toJava.Utils;
   import org.xml.sax.Attributes;
   import org.xml.sax.SAXException;
  +import javax.xml.soap.SOAPElement;
  +import java.util.ArrayList;
  +import java.util.Enumeration;
   
   import javax.xml.namespace.QName;
   
  @@ -178,6 +182,11 @@
   
               for (int i = 0; i < operations.length; i++) {
                   OperationDesc operation = operations[i];
  +
  +                // See if any information is coming from a header
  +                boolean needHeaderProcessing =
  +                    needHeaderProcessing(operation, isResponse);
  +
                   if (operation.getNumInParams() >= numParams || 
                       elementIsFirstParam ||
                       operation.getStyle() == Style.WRAPPED) {
  @@ -206,6 +215,15 @@
   
                           publishToHandler((org.xml.sax.ContentHandler) context);
   
  +                        // If parameter values are located in headers,
  +                        // get the information and publish the header
  +                        // elements to the rpc handler.
  +                        if (needHeaderProcessing) {
  +                            processHeaders(operation, isResponse,
  +                                           context, rpcHandler);
  +                        }
  +
  +
                           // Success!!  This is the right one...
                           msgContext.setOperation(operation);
                           return;
  @@ -214,6 +232,12 @@
                           savedException = e;
                           params = new Vector();
                           continue;
  +                    }  catch (AxisFault e) {
  +                        // Thrown by getHeadersByName...
  +                        // If there was a problem, try the next one.
  +                        savedException = new SAXException(e);
  +                        params = new Vector();
  +                        continue;
                       }
                   }
               }
  @@ -308,5 +332,120 @@
           if (isRPC || noParams) {
               context.endElement();
           }
  +    }
  +
  +    /**
  +     * needHeaderProcessing
  +     * @param operation OperationDesc
  +     * @param isResponse boolean indicates if request or response message
  +     * @return true if the operation description indicates parameters/results
  +     * are located in the soap header.
  +     */
  +    private boolean needHeaderProcessing(OperationDesc operation, 
  +                                         boolean isResponse) {
  +
  +        // Search parameters/return to see if any indicate
  +        // that instance data is contained in the header.
  +        ArrayList paramDescs = operation.getParameters();
  +        if (paramDescs != null) {
  +            for (int j=0; j<paramDescs.size(); j++) {
  +                ParameterDesc paramDesc = 
  +                    (ParameterDesc) paramDescs.get(j);
  +                if ((!isResponse && paramDesc.isInHeader()) ||
  +                    (isResponse && paramDesc.isOutHeader())) {
  +                    return true;
  +                }
  +            }
  +        }
  +        if (isResponse && 
  +            operation.getReturnParamDesc() != null &&
  +            operation.getReturnParamDesc().isOutHeader()) {
  +            return true;
  +        }        
  +        return false;
  +    }
  +
  +    /**
  +     * needHeaderProcessing
  +     * @param opereration OperationDesc
  +     * @param isResponse boolean indicates if request or response message
  +     * @param context DeserializationContext
  +     * @param handler RPCHandler used to deserialize parameters
  +     * @return true if the operation description indicates parameters/results
  +     * are located in the soap header.
  +     */
  +    private void processHeaders(OperationDesc operation,
  +                                boolean isResponse,
  +                                DeserializationContext context,
  +                                RPCHandler handler)
  +        throws AxisFault, SAXException
  +    {
  +        // Inform handler that subsequent elements come from
  +        // the header
  +
  +        handler.setHeaderElement(true);
  +        // Get the soap envelope
  +        SOAPElement envelope = getParentElement();
  +        while (envelope != null &&
  +               !(envelope instanceof SOAPEnvelope)) {
  +            envelope = envelope.getParentElement();
  +        }
  +        if (envelope == null) 
  +            return;
  +
  +        // Find parameters that have instance
  +        // data in the header.
  +        ArrayList paramDescs = operation.getParameters();
  +        if (paramDescs != null) {
  +            for (int j=0; j<paramDescs.size(); j++) {
  +                ParameterDesc paramDesc = (ParameterDesc) paramDescs.get(j);
  +                if ((!isResponse && paramDesc.isInHeader()) ||
  +                    (isResponse && paramDesc.isOutHeader())) {
  +                    // Get the headers that match the parameter's
  +                    // QName
  +                    Enumeration headers = ((SOAPEnvelope) envelope).
  +                        getHeadersByName(
  +                           paramDesc.getQName().getNamespaceURI(),
  +                           paramDesc.getQName().getLocalPart(),
  +                           true);
  +                    // Publish each of the found elements to the
  +                    // handler.  The pushElementHandler and
  +                    // setCurElement calls are necessary to 
  +                    // have the message element recognized as a
  +                    // child of the RPCElement.
  +                    while(headers != null &&
  +                          headers.hasMoreElements()) {
  +                        context.pushElementHandler(handler);
  +                        context.setCurElement(null);
  +                        ((MessageElement) headers.nextElement()).
  +                            publishToHandler(
  +                               (org.xml.sax.ContentHandler)context);
  +                    }
  +                }
  +            }
  +        }
  +        
  +        // Now do the same processing for the return parameter.
  +        if (isResponse && 
  +            operation.getReturnParamDesc() != null &&
  +            operation.getReturnParamDesc().isOutHeader()) {
  +            ParameterDesc paramDesc = operation.getReturnParamDesc();
  +            Enumeration headers =
  +                ((SOAPEnvelope) envelope).
  +                getHeadersByName(
  +                    paramDesc.getQName().getNamespaceURI(),
  +                    paramDesc.getQName().getLocalPart(),
  +                    true);
  +            while(headers != null &&
  +                  headers.hasMoreElements()) {
  +                context.pushElementHandler(handler);
  +                context.setCurElement(null);
  +                
  +                ((MessageElement) headers.nextElement()).
  +                    publishToHandler((org.xml.sax.ContentHandler)context);
  +            }                                                                 
  +        }
  +
  +        handler.setHeaderElement(false);
       }
   }
  
  
  
  1.65.4.1  +24 -0     xml-axis/java/src/org/apache/axis/message/RPCHandler.java
  
  Index: RPCHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/message/RPCHandler.java,v
  retrieving revision 1.65
  retrieving revision 1.65.4.1
  diff -u -r1.65 -r1.65.4.1
  --- RPCHandler.java	25 Sep 2002 16:35:33 -0000	1.65
  +++ RPCHandler.java	2 Oct 2002 20:39:06 -0000	1.65.4.1
  @@ -104,6 +104,7 @@
       private RPCParam currentParam = null;
       private boolean isResponse;
       private OperationDesc operation;
  +    private boolean isHeaderElement;
   
       public RPCHandler(RPCElement rpcElem, boolean isResponse)
           throws SAXException
  @@ -117,6 +118,15 @@
       }
   
       /**
  +     * Indicate RPCHandler is processing header elements
  +     * @param value boolean indicating whether
  +     * header elements are being processed.
  +     */
  +    public void setHeaderElement(boolean value) {
  +        isHeaderElement = true;
  +    }
  +
  +    /**
        * This method is invoked when an element start tag is encountered.
        * The purpose of this method in RPCHandler is to reset variables
        * (this allows re-use of RPCHandlers)
  @@ -225,6 +235,16 @@
               if (paramDesc == null) {
                   throw new SAXException(Messages.getMessage("noParmDesc"));
               }
  +            // Make sure that we don't find body parameters that should
  +            // be in the header
  +            if (!isHeaderElement &&
  +                ((isResponse && paramDesc.isOutHeader()) ||
  +                 (!isResponse && paramDesc.isInHeader()))) {
  +                throw new SAXException(
  +                    Messages.getMessage("expectedHeaderParam", 
  +                                        paramDesc.getQName().toString()));
  +            }
  +
               destClass = paramDesc.getJavaType();
               
               // Keep the association so we can use it later
  @@ -311,6 +331,10 @@
                              DeserializationContext context)
           throws SAXException
       {
  +        // endElement may not be called in all circumstances.
  +        // In addition, onStartChild may be called after endElement
  +        // (for header parameter/response processing).  
  +        // So please don't add important logic to this method.
           if (log.isDebugEnabled()) {
               log.debug(Messages.getMessage("setProp00",
                       "MessageContext", "RPCHandler.endElement()."));
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.1   +91 -0     xml-axis/java/src/org/apache/axis/message/Attic/RPCHeaderParam.java
  
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.96.6.1  +25 -3     xml-axis/java/src/org/apache/axis/providers/java/RPCProvider.java
  
  Index: RPCProvider.java
  ===================================================================
  RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/providers/java/RPCProvider.java,v
  retrieving revision 1.96
  retrieving revision 1.96.6.1
  diff -u -r1.96 -r1.96.6.1
  --- RPCProvider.java	24 Sep 2002 16:03:38 -0000	1.96
  +++ RPCProvider.java	2 Oct 2002 20:39:07 -0000	1.96.6.1
  @@ -67,6 +67,7 @@
   import org.apache.axis.message.RPCParam;
   import org.apache.axis.message.SOAPEnvelope;
   import org.apache.axis.message.SOAPBodyElement;
  +import org.apache.axis.message.RPCHeaderParam;
   import org.apache.axis.soap.SOAPConstants;
   import org.apache.axis.utils.ClassUtils;
   import org.apache.axis.utils.JavaUtils;
  @@ -320,6 +321,7 @@
           resBody.setNamespaceURI( body.getNamespaceURI() );
           resBody.setEncodingStyle(msgContext.getEncodingStyle());
   
  +        try {
           // Return first
           if ( operation.getMethod().getReturnType() != Void.TYPE ) {
               QName returnQName = operation.getReturnQName();
  @@ -332,12 +334,22 @@
               {
                   RPCParam result = new RPCParam
                      (Constants.QNAME_RPC_RESULT, returnQName.getLocalPart());
  -                resBody.addParam(result);
  +                if (!operation.isReturnHeader()) {
  +                    resBody.addParam(result);
  +                } else {
  +                    resEnv.addHeader(new RPCHeaderParam(result));
  +                }
  +
               }
   
               RPCParam param = new RPCParam(returnQName, objRes);
               param.setParamDesc(operation.getReturnParamDesc());
  -            resBody.addParam(param);
  +            if (!operation.isReturnHeader()) {
  +                resBody.addParam(param);
  +            } else { 
  +                resEnv.addHeader(new RPCHeaderParam(param));
  +            }
  +                
           }
   
           // Then any other out params
  @@ -350,8 +362,18 @@
                   ParameterDesc paramDesc = param.getParamDesc();
   
                   param.setValue(value);
  -                resBody.addParam(param);
  +                if (paramDesc != null &&
  +                    paramDesc.isOutHeader()) {
  +                    resEnv.addHeader(new RPCHeaderParam(param));
  +                } else {
  +                    resBody.addParam(param);
  +                }
               }
  +        }
  +
  +        } catch (Exception e) {
  +            System.out.println(e);
  +            throw e;
           }
   
           resEnv.addBodyElement(resBody);