Ok, I am now sure that I use wrapped/doc/lit on both sides, I have removed the @SOAPBinding on the Java side and the mentioned RegisterInvokeOptions call instructs Delphi to use "document-literal style and the types for input and output values have not been unwound to create a method call" (from the Delphi doc).

But the Web service call from Delphi always produces <null> values as incoming parameters in my Java Web service, without any exceptions or warnings on the CXF side. This is the request that Delphi sends now:

<?xml version="1.0"?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
   xmlns:xsd="http://www.w3.org/2001/XMLSchema";
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
   <SOAP-ENV:Body>
       <ExecuteJob xmlns="http://annuaire.ciss.lu";>
           <JobName>TestFromDelphi</JobName>
           <JobParamsIn>
               <string>valueDelphi1</string>
               <string>valueDelphi2</string>
           </JobParamsIn>
           <JobParamBean>
               <key>keyDelphi</key>
               <value>2</value>
           </JobParamBean>
       </ExecuteJob>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The Java client (which still works correctly) sends the following request:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";>
   <soap:Body>
       <ns1:ExecuteJob xmlns:ns1="http://annuaire.ciss.lu";>
           <JobName>TestFromJava</JobName>
           <JobParamsIn>valueJava1</JobParamsIn>
           <JobParamsIn>valueJava2</JobParamsIn>
           <JobParamBean>
               <key>keyJava</key>
               <value>1</value>
           </JobParamBean>
       </ns1:ExecuteJob>
   </soap:Body>
</soap:Envelope>

As there are some minor differences, is the request from Delphi incorrect / incompatible? If so, I will perhaps continue to investigate the issue on a Delphi forum resp. send a bug report to Codegear.
Thanks in advance.

Pierre

Daniel Kulp wrote:
<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
    xmlns:xsd="http://www.w3.org/2001/XMLSchema";
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
    <SOAP-ENV:Body>
        <SOAP-ENV:string>TestFromDelphi</SOAP-ENV:string>
        <SOAP-ENV:stringArray>

Umm... why would the string and stringArray things be in the SOAP-ENV namespace? That DEFINITELY looks bad. Looks like some more Delphi configuration is needed somehow.


That said, you should definitely use a wrapped/doc/lit, not bare. So the message should look something like;

<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
    xmlns:xsd="http://www.w3.org/2001/XMLSchema";
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
     <SOAP-ENV:Body>
         <ns1:executeJob xmlns:ns1="......">
           <JobName>TestFromDelphi</JobName>
           ....
         </ns1:executeJob>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Dan



On Monday 25 February 2008, pierre post wrote:
Thanks for pointing me in the right direction, Ian. I also suspected
that it's an encoding problem but I wasn't sure.

Unfortunately, after some more trial&error tests, I didn't come to a
positive result. Removing the @SOAPBinding i.e. using wrapped
document/literal/wrapped generates a far more complex Delphi unit
(that would be the least of the problems) but furthermore, now no
parameters at all are correctly received in the Java Web service (only
<null> values).

I looked up the Delphi documentation and after a little research added
the line

InvRegistry.RegisterInvokeOptions(TypeInfo(JobService), [ioDocument,
ioLiteral]);

in my Delphi client, so Delphi *should* definitively use
document/literal encoding. But no change.

But, if I use the document/literal/bare encoding, I receive the
following error message from CXF:

25-Feb-2008 11:05:07 org.apache.cxf.phase.PhaseInterceptorChain
doIntercept INFO: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Message part
{http://schemas.xmlsoap.org/soap/envelope/}string was not recognized.
    at
org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLi
teralInInterceptor.java:178) at
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseIntercepto
rChain.java:208) at
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitia
tionObserver.java:77) ...

Delphi sends the following SOAP request:

<?xml version="1.0"?>
<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
    xmlns:xsd="http://www.w3.org/2001/XMLSchema";
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
    <SOAP-ENV:Body>
        <SOAP-ENV:string>TestFromDelphi</SOAP-ENV:string>
        <SOAP-ENV:stringArray>
            <string>valueDelphi1</string>
            <string>valueDelphi2</string>
        </SOAP-ENV:stringArray>
        <JobParamBean xmlns="http://annuaire.ciss.lu";>
            <key>keyDelphi</key>
            <value>2</value>
        </JobParamBean>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

This whole encoding issue is getting rather frustrating for me, having
in mind Web services should improve interoperability ... :-(

Pierre

Ian Roberts wrote:
The Delphi client is trying to use SOAP encoding (RPC/encoded) but
the CXF service expects RPC/literal.  I don't know Delphi, is there
any configuration option to tell it to use literal rather than
encoded? Or if Delphi can't do RPC/literal, try removing the
@SOAPBinding annotation from your service to make it use wrapped
document/literal and see if Delphi likes that any better.

Ian

pierre post wrote:
Hi all,

I have a problem when calling an Apache CXF Web service (CXF
version is 2.0.4) running under Apache Tomcat 6 from a Delphi
client program. The third parameter "JobParamBean" that I receive
in my Web service on Tomcat is always null but there is no
exception or any other hint in the Tomcat logs. The parameter is a
simple JavaBean class (uses getters and setters for all properties
and implements serializable). Moreover, the problem does not appear
when calling the same Web service from a Java client. This is my
Web service:

@WebService(name="JobService",
targetNamespace="http://annuaire.ciss.lu";)
@SOAPBinding(style=Style.RPC)
public interface JobService {
  @WebMethod(operationName="ExecuteJob")
  @WebResult(name="JobParamsOut")
  public String[] executeJob(@WebParam(name="JobName") String
jobName, @WebParam(name="JobParamsIn") String[] input,
      @WebParam(name="JobParamBean") JobServiceParam param) throws
ServiceException;
}

When calling this web service from the Delphi application (using
the latest available HTTPRIO component and WSDL importer), the
corresponding generated SOAP request produces "null" as
JobParamBean parameter:

<?xml version="1.0"?>
<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/";
  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/";>
  <SOAP-ENV:Body
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
xmlns:NS2="http://annuaire.ciss.lu";>
      <NS1:ExecuteJob xmlns:NS1="http://annuaire.ciss.lu";>
          <JobName xsi:type="xsd:string">TestFromDelphi</JobName>
          <JobParamsIn xsi:type="SOAP-ENC:Array"
              SOAP-ENC:arrayType="xsd:string[2]">
              <item>valueDelphi1</item>
              <item>valueDelphi2</item>
          </JobParamsIn>
          <JobParamBean href="#1" />
      </NS1:ExecuteJob>
      <NS2:JobServiceParamType id="1"
          xsi:type="NS2:JobServiceParamType">
          <key xsi:type="xsd:string">paramkey</key>
          <value xsi:type="xsd:string">paramval</value>
      </NS2:JobServiceParamType>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I tried to call the same web service from Java (also using Apache
CXF 2.0.4) and the generated SOAP request correctly creates a
JobParamBean instance:

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/";> <soap:Body>
      <ns1:ExecuteJob xmlns:ns1="http://annuaire.ciss.lu";>
          <JobName>TestFromJava</JobName>
          <JobParamsIn>
              <item>valueJava1</item>
              <item>valueJava2</item>
          </JobParamsIn>
          <JobParamBean>
              <key>keyJava</key>
              <value
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:ns3="http://www.w3.org/2001/XMLSchema"; xsi:type="ns3:int">
                  1
              </value>
          </JobParamBean>
      </ns1:ExecuteJob>
  </soap:Body>
</soap:Envelope>

I noticed that the Delphi SOAP request uses a reference for the
third parameter (href="#1") but the Java SOAP request does not. Is
it possible that CXF doesn't support this kind of references? Is
there a workaround in CXF to support the request or perhaps in
Delphi to suppress the use of the reference?

Thanks in advance for any comments on this issue.

Best regards,
Pierre Post








Reply via email to