簡體   English   中英

消費來自SABA的Web服務

[英]Consuming webservice from SABA

我需要自定義SABA頁面,以便在特殊的呈現頁面上添加HTML按鈕。 按下按鈕,必須調用Web服務才能根據輸入參數獲得答案,因此請采取適當的措施。

WS接受JSON變量作為輸入,例如:{“ check”:int,“ planTitle”:“ ...”}

調用WS之后(即:在uri上調用它,例如: http : //www.blablabla.com :8080/resource/services/service1),我將獲得一個帶有結果的JSON變量。

服務器返回的經典肥皂信封為:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns1:getInfoResponse xmlns:ns1="http://www.blablabla.com/">{"check":1,......}</ns1:getInfoResponse> 

還要考慮一下,Saba服務器和Web服務服務器可以托管在不同的計算機上,但是可以在相同的Intranet上。

現在,我有兩種可能的解決方案:

  1. 在服務器上用Java實現Web服務.....但是我不明白這種工作的簡單性或有效性.....(客戶端?)

  2. 使用Jquery或直接使用Javascript在HTML呈現的頁面中直接調用Web服務,並以優雅和簡單的方式實時獲取結果。 唯一的問題在於可能存在的跨瀏覽器問題或其他也基於SABA SW限制的問題,但是我在Intranet上的映像例如可以解決跨瀏覽器方面的問題。

那么您可以建議我哪種解決方案,為什么呢?

經過一段時間,沒有任何幫助,我自己解決了問題。 因此,我希望與大家分享所使用的方法。

在Remy Blom插件(請參閱: http : //plugins.jquery.com/soap/ )此刻,要使用jQuery從客戶端使用Web服務,可以認為是有效的替代方法,它足夠有效,因此可以完成此工作。為您盡可能簡單。 此插件必須再次進行改進,但非常易於使用。 當然,它基於ajax回調。 因此,您可以想象,如果沒有可能管理服務器端配置以允許“訪問控制允許原點”,並且主要是如果我們需要從Internet連接到Intranet Web服務服務器,則需要擴大視野。

根據我的經驗,解決這種情況的最好,最簡單的方法可能是:

  1. 編寫服務器端Web服務以代理請求並返回結果
  2. 編寫服務器端代理頁面

我喜歡編寫一個簡單而最少的服務器端網頁,只是為了使用Web服務並將答案返回給調用。 必須通過post / get調用將參數傳遞到此類頁面,並且結果頁面必須包含適當的字段以包含結果。

為什么我更喜歡這樣做? 因為,在服務器端使用最少的代碼行,我還可以向客戶提供以下可能性:測試WS的調用是否正確運行,並由客戶即時確定一些參數,然后在瀏覽器上的html頁面上查找結果。

對我來說,在服務器端創建代理,在客戶端使用它,讓客戶自己測試它是正確的折衷方案。

安全問題? 不好了。 它們完全取決於添加代理頁面的Web服務器的安全性。

該解決方案也足夠靈活,可用於:java,c#,nodejs,php,perl,......

因此,我擁有哪種類型的Web服務器絕對不重要:有時候,Saba的唯一用語可能會讓您感到困惑。

讓我們描述一下解決方案。

在服務器端,我創建了一個簡單的Saba網頁,主要包含以下服務器代碼,以便從請求中獲取輸入參數,構建Web服務調用並使用它。 結果,滿足了輸出字段。 Java代碼(使用軸1)為:

    try {
    if (wsEndPoint == null || wsEndPoint.trim().length() == 0 || wsNAME == null || wsNAME.trim().length() == 0 ||
        id == null || id.trim().length() == 0 || code == null || code.trim().length() == 0) {
        retVal = "Error: mandatory parameter missing.";
    } else {
        Service  service = new Service();
        Call call = (Call)service.createCall();

        call.setTargetEndpointAddress(new java.net.URL(wsEndPoint));
        call.setOperationName(new QName("http://service.name.it/", wsNAME));
        call.addParameter(new QName("http://service.name.it/", "arg0"), new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
        call.addParameter(new QName("http://service.name.it/", "arg1"), new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
        call.setSOAPActionURI("");
        call.setEncodingStyle(null);
        call.setProperty(Call.SEND_TYPE_ATTR, Boolean.FALSE);
        call.setProperty(AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);

        retVal = ((String)call.invoke(new Object[] {id, code})).trim();
    }
} catch (Exception e) {
    retVal = String.format("Error: %s.", e.getMessage());

}

參考前面的代碼的相應客戶端頁面的核心是:

    <form method="POST" name="myform">
    <table border="0" width="75%">
     <tbody>
        <tr>
           <td>Web Service proxy page</td>
        </tr>
        <tr>
           <td>ws End Point</td>
           <td><input name="wsEndPoint" type="text"></td>
        </tr>
        <tr>
          <td>ws Function Name</td>
          <td><input name="wsNAME" type="text"></td>
        </tr>
        <tr>
          <td><ID</td>
          <td><input name="ID" type="text"></td>
        </tr>
        <tr>
          <td>code</td>
          <td><input name="CODE" type="text"></td>
        </tr>
        <tr>
          <td>return Value</td>
          <td><input name="retVal" type="text"></td>
        </tr>
      </tbody>
      </table>
</form>

現在,只需測試頁面即可在瀏覽器中打開一個鏈接,如下所示:

http://localhost/myproxypage?ID=312001&CODE=CV2W1-OF00MA&wsEndPoint=http:%2F%2Ffedora:9000%2Faxis%2Fservices%2FwsInfo&wsNAME=mywsname

如果客戶離您很遠,您可以將頁面發送給他,並要求使用他希望的參數運行前一個鏈接,並讀取結果字段。 這可以幫助您完成這部分工作。

完成服務器端代理頁面后,我們可以考慮在需要進行更改的頁面中使用javascript,例如:添加一個按鈕以動態驗證最終用戶輸入的兩個值是否正確(通過調用Web服務)。 因為我沒有足夠的知識,並且我需要使用一個好的,靈活的解決方案來加快速度,所以我更喜歡使用javascript和jquery庫來創建一個簡單的腳本,以將其添加到感興趣的代碼行中,如下所示:

....... some globals and locals..... ...... function wsCall(callback) { var IDVal = _idAzioneObj.val().trim(); if ((wsCallCanStart == false) || ((typeof callback !== 'function') && (IDVal.length == 0))) { return; // when waiting for ajax to complete or when called from the save button and the input field is empty.....nothing to do } if ((typeof callback === 'function') && (IDVal.length == 0)) { callback(); // on save click and input field null......continue with normal flow return; } wsCallCanStart = false; jQuery(' ').css('cursor', 'progress'); jQuery.ajax({ type: 'POST', url: wsProxyPage, async: true, data: { ID : _idAzioneObj.val(), CODE : codiceCorso, wsEndPoint : wsEndPoint, wsNAME : wsName }, }).done(function(data, textStatus, jqXHR) { var retValObj = jQuery(data).find('input[name="retVal"]'); if (retValObj.length > 0) { var retValJson = null; try { retValJson = jQuery.parseJSON(retValObj.val()); } catch (e) { retValJson = null; } if (retValJson != null) { try { var check = retValJson.check; var retval1 = retValJson.retval1; var retval2 = retValJson.retval2; var retval3 = retValJson.retval3; if (check < 0 || check > 6) { check = 6; } if (check == 1) { // all ok: use new variables.... if (typeof callback === 'function') { callback(); // continue with nornal flow return; } else { displayMsg(RetMsg[check]); // display message to user } } else { displayMsg(RetMsg[check]); } } catch (e) { displayMsg(genericErrorMsg); } } else { displayMsg(err, retValObj.val()); } } else { displayMsg(genericErrorMsg); } }).fail(function(jqXHR, textStatus, errorThrown) { displayMsg(genericErrorMsg); }).always(function() { wsCallCanStart = true; jQuery(' ').css('cursor', 'auto'); }); };

 ...... some other code ..... jQuery(function() { _idAzioneObj = jQuery('input[name="localname"]'); if (_idAzioneObj.is(':not([type=hidden])')) { _idAzioneObj.after('<a class="sbWDKButton" href="javascript:void(\\'check\\')" onclick="wsCall(null);return false;" title="' + btnWcTitle + '"><span class="sbDummy">' + btnWcTitle + '</span></a>'); var SaveObj = jQuery('a[href="javascript:void(\\'save\\')"]'); var saveOnClickFuncStr = SaveObj.attr('onclick'); SaveObj.attr('onclick', 'wsCall(function(){' + saveOnClickFuncStr + '});return false;'); } }); 

這樣,我僅使用javascript和promise技術就克服了服務器端缺乏知識的情況:如果最終用戶單擊驗證按鈕,則通過代理頁面調用ws,否則將發生相同的操作,並且如果ws回答了其余流程可以在不了解Saba的情況下照常執行。

就是這些

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM