繁体   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