2011-12-19 27 views
5

Chúng tôi cần có khả năng gọi một dịch vụ web nội bộ từ mã COBOL chạy trên iSeries LPAR (V6R1). Tôi đã làm việc thông qua một ví dụ hoàn chỉnh mà tôi đã có thể tìm thấy trực tuyến here. Vì vậy, bước tiếp theo của tôi là cố gắng lặp lại quy trình và gọi một trong các dịch vụ web hiện có của chúng tôi.Tôi làm cách nào để gọi dịch vụ web từ iSeries COBOL?

Tôi đã sử dụng lệnh WSDL2WS từ QSH để tạo ra các sơ đồ khách C. Tôi đã sửa đổi chương trình ứng dụng khách COBOL mẫu và thử gọi đến dịch vụ web của tôi. Các vấn đề mà tôi đang chạy vào dường như có liên quan đến thực tế là các ví dụ C phương pháp khách hàng đang trở về con trỏ và mã COBOL được giao cho con trỏ. Tôi nghi ngờ rằng một lỗi trong mã COBOL của tôi là gốc rễ của vấn đề của tôi, bởi vì phương pháp C rằng WSDL2WS tạo ra cho phương pháp dịch vụ web của tôi trả về một xsdc_string đơn giản không phải là một con trỏ đến một loại quả tùy chỉnh:

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; 
} 

tôi có thể thiết lập dịch vụ web ở chế độ gỡ lỗi và có thể thấy cuộc gọi từ iSeries khi tôi chạy chương trình gọi các mô-đun COBOL và C. Tôi cũng có thể thấy rằng tôi đang quay trở lại một giá trị chuỗi đơn giản.

Sự cố xảy ra khi chương trình COBOL cố gắng lấy giá trị trả lại và sử dụng nó. Tôi tin rằng các bit liên quan của mã COBOL là:

LINKAGE PROCEDURE FOR "TestSuccessfulMessage" 
       USING ALL DESCRIBED  

LINKAGE SECTION.      
01 LookupResult   PIC X(1000). 

CALL PROCEDURE "TestSuccessfulMessage" 
USING BY VALUE STUB    
RETURNING LookupResult.   

Tôi nhận được mã MCH3601 khi mã được mã hóa theo cách này. Nếu tôi trở lại vào một con trỏ và sau đó thiết lập địa chỉ để LookupResult, tôi kết thúc với một giá trị null.

Tôi hy vọng rằng tôi chỉ thiếu một chi tiết nhỏ ở đâu đó. Tôi có rất ít kinh nghiệm COBOL. Tôi chỉ đang cố gắng tạo một ứng dụng tham chiếu làm bằng chứng khái niệm cho một nhóm khác trong công ty của chúng tôi. Bất kỳ trợ giúp, hoặc đề xuất những gì để thử sẽ được đánh giá cao. Tôi có thể cung cấp thêm mã.

Cập nhật: Tôi đã thử di chuyển khai báo LookupResult vào bộ nhớ hoạt động. Trong khi đó loại bỏ các lỗi MCH3601, tôi chỉ có một loạt các dữ liệu rác trong màn hình của tôi. Tôi có thể xem thông tin về phiên iSeries của tôi (ví dụ: deviceID, v.v ...) bên trong dữ liệu.

Tôi cũng đã thử rời khỏi LookupResult trong phần liên kết và tạo con trỏ trong bộ nhớ làm việc. Sau đó, tôi đã thêm một "SET Address of LookupResult TO ResultPointer". Một lần nữa, cuộc gọi kết thúc mà không có lỗi, nhưng khi tôi hiển thị LookupResult tôi nhận được dữ liệu rác. Tuy nhiên, nó khác với dữ liệu quay lại nếu tôi trở lại thẳng vào LookupResult. Tôi có thể thấy các mảnh của phong bì SOAP trong dữ liệu này.

Cuối cùng: Tất cả những thay đổi mà tôi phải thực hiện đều có trong mã COBOL. Dưới đây là các mảnh có liên quan:

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. 

Trả lời

4

Nếu tôi trở thành một con trỏ và sau đó thiết lập các địa chỉ để LookupResult, tôi kết thúc với một giá trị null.

Tôi là người COBOL, nhưng không phải trên iSeries. Emptor caveat.

Nếu xsdc__string phân giải thành con trỏ, thì mã COBOL của bạn phải có biến loại POINTER cho phần RETURNING của CALL. Có lẽ hàm C trong thực tế trả về NULL, mã chắc chắn cho phép nó - có thể axiscCallInitialize không trả về AXISC_SUCCESS.

Ít nhất trên z/OS, bạn sẽ muốn biến con trỏ COBOL ở trong Bộ lưu trữ làm việc hoặc Bộ nhớ cục bộ, và sau đó bạn sẽ THIẾT LẬP ĐỊA CHỈ LookupResult TO biến con trỏ đó. Tôi cho rằng điều đó không thay đổi chỉ vì bạn đang ở trên một kiến ​​trúc máy khác.

... FWIW

+0

Cảm ơn bạn. Tôi đã thử sử dụng một con trỏ và lệnh SET ADDRESS OF, nhưng tại thời điểm tôi tin rằng khai báo con trỏ của tôi nằm trong phần liên kết. Tôi sẽ cố gắng di chuyển nó để lưu trữ làm việc. Tôi cũng đã bước vào mã C trong chế độ gỡ lỗi. Tôi có thể thấy rằng Ret bắt đầu như NULL, nhưng sau khi cuộc gọi nó có một giá trị, mà trong trình gỡ lỗi iSeries cho thấy như Ret = SPP: DA1A1DDC05014450. –

+1

Tôi đang xem xét câu trả lời này vì nó chứa thông tin về thay đổi mã mà tôi cần phải thực hiện. Tôi tạo ra một biến con trỏ trong lưu trữ làm việc. Tôi đã thay đổi cuộc gọi để sử dụng cú pháp "RETURNING INTO myPointer" và sử dụng lệnh Set Address Of như bạn đã đề xuất. Cảm ơn một lần nữa. –

Các vấn đề liên quan