如何从iSeries COBOL中调用web服务



我们需要能够从运行在iSeries LPAR (V6R1)上的COBOL代码调用内部web服务。我在网上找到了一个完整的例子。所以,我的下一步是尝试重复这个过程,调用我们现有的一个web服务。

我使用了来自QSH的WSDL2WS命令来生成C客户机存根。我修改了示例COBOL客户机程序,并尝试调用我的web服务。我遇到的问题似乎与示例C客户端方法返回指针和COBOL代码将它们分配给指针有关。我怀疑COBOL代码中的错误是问题的根源,因为WSDL2WS为我的web服务方法创建的C方法返回一个简单的xsdc_string,而不是指向自定义结果类型的指针:

xsdc__string TestUnsuccessfulMessage(AXISCHANDLE stub)
{
    AXISCHANDLE call = axiscStubGetCall(stub);
    xsdc__string Ret = NULL;
    axiscCallSetSoapFaultNamespace(call, "http://myserver/PSItemMaintenance/ItemMaintenanceService.svc");

    // ======================================================================
    // Initialize client engine, set SOAP version, SOAPAction, operation, etc.
    // ======================================================================
    if (AXISC_SUCCESS != axiscCallInitialize(call, C_DOC_PROVIDER ))
        return Ret;
    if (NULL==axiscCallGetTransportProperty(call,"SOAPAction",0))
        axiscCallSetTransportProperty(call,AXISC_SOAPACTION_HEADER , "http://tempuri.org/IItemMaintenanceService/TestUnsuccessfulMessage");
    axiscCallSetSOAPVersion(call, SOAP_VER_1_1);
    axiscCallSetOperation(call, "TestUnsuccessfulMessage", "http://tempuri.org/");
    // ======================================================================
    // Apply SSL configuration properties and user-set SOAP headers.
    // ======================================================================
    axiscStubIncludeSecure(stub);
    axiscStubApplyUserPreferences(stub);

    // ======================================================================
    // Invoke web service, send/receive operation. Handle output parameters, if any.
    // ======================================================================
    if (AXISC_SUCCESS == axiscCallSendAndReceive(call))
    {
        if(AXISC_SUCCESS == axiscCallValidateMessage(call, "TestUnsuccessfulMessageResponse", "http://tempuri.org/", true_))
        {
            Ret = axiscCallGetElementAsString(call, "TestUnsuccessfulMessageResult", 0);
        }
        axiscStubCheckForExtraneousElements(stub);
    }
    axiscCallUnInitialize(call);
    return Ret;
}

我可以在调试模式下设置web服务,并且可以在运行调用COBOL和C模块的程序时看到来自iSeries的调用。我还可以看到我返回了一个简单的字符串值。

当COBOL程序试图获取返回值并使用它时,问题就出现了。我认为COBOL代码的相关部分是:

LINKAGE PROCEDURE FOR "TestSuccessfulMessage"
                 USING ALL DESCRIBED    
LINKAGE SECTION.                     
 01 LookupResult         PIC X(1000).  
CALL PROCEDURE "TestSuccessfulMessage"
 USING BY VALUE STUB              
 RETURNING LookupResult.          

当它以这种方式编码时,我得到一个MCH3601。如果我返回到一个指针,然后将地址设置为LookupResult,我最终会得到一个空值。

我希望我只是遗漏了一个小细节。我几乎没有什么COBOL经验。我只是想创建一个参考应用程序,作为我们公司另一个团队的概念证明。任何帮助,或建议什么尝试将不胜感激。我可以提供更多的代码。

Update:我尝试将LookupResult声明移动到工作存储中。虽然这消除了MCH3601错误,但我在显示器中得到了一堆垃圾数据。我可以在数据中看到关于我的iSeries会话(即deviceID等)的信息。

我还尝试在链接部分中留下LookupResult并在工作存储中创建指针。然后我添加了一个"SET地址的查找结果到ResultPointer"。同样,调用结束时没有出现错误,但是当我显示LookupResult时,我得到了垃圾数据。但是,如果我直接返回到lookpresult,它与返回的数据不同。我可以在这个数据中看到SOAP信封的片段。

最后:

我必须做的所有更改都在COBOL代码中。以下是相关内容:

WORKING-STORAGE SECTION.              
01 Endpoint             PIC X(100).   
01 STUB                 USAGE POINTER.
01 ResultPointer        USAGE POINTER.
LINKAGE SECTION.                      
01 pszEndpoint          PIC X(100).   
01 LookupResult         PIC X(7).   
CALL PROCEDURE "TestSuccessfulMessage"       
     USING BY VALUE STUB                     
     RETURNING INTO ResultPointer.           
SET Address of LookupResult TO ResultPointer.

如果我返回到一个指针,然后将地址设置为LookupResult,那么我以空值结束。

我是一个COBOL的人,但不是在iSeries。购者自慎。

如果xsdc__string解析为指针,那么您的COBOL代码应该有一个指针类型的变量用于调用的返回部分。也许C函数实际上返回NULL,代码当然允许它——也许axiscCallInitialize没有返回AXISC_SUCCESS。

至少在z/OS上,您将希望COBOL指针变量位于工作存储或本地存储中,然后将ADDRESS OF LookupResult设置为该指针变量。我想这不会因为你在不同的机器架构上而改变。

就其价值而言

相关内容

  • 没有找到相关文章

最新更新