我需要自定义 SABA 页面,以便在特殊呈现的页面上添加 HTML 按钮。 按下按钮时,必须调用 Web 服务来根据输入参数获取答案,从而采取适当的操作。
WS 接受 JSON 变量作为输入,例如: { “检查”:整数, “计划标题”:“...” }
调用 WS 后(即:在 uri 上调用它,如: http://www.blablabla.com:8080/resource/services/service1 我将获得一个包含结果的 JSON 变量。
服务器返回的经典 SOAP 信封是:
<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 上。
现在,我有两种可能的解决方案:
在服务器上用java实现一个web服务......但我无法理解这种努力的简单性或有效性......(客户端?)
<使用 Jquery 或直接 Javascript 直接在 HTML 渲染页面中调用 Web 服务并即时获取结果 充满优雅和简约。唯一的问题在于可能的跨浏览器问题或其他也基于 SABA 软件限制的问题, 但我想象在内联网上,例如,跨浏览器方面是可以克服的。
那么您可以建议我使用哪种解决方案,为什么?
最佳答案
过了一段时间,在没有任何帮助的情况下,我自己解决了这个问题。所以我想和大家分享一下所使用的方法。
目前要使用 jQuery 从客户端使用 Remy Blom 插件的 Web 服务(引用: http://plugins.jquery.com/soap/ ) 可以被认为是一个有效的替代方案,足够有效,以便它尽可能简单地为您完成工作。 这个插件必须再次改进,但它非常容易使用。当然,它基于 ajax 回调。 那么您如何想象,如果无法管理服务器端配置以允许“Access-Control-Allow-Origin”并且主要 如果我们需要从互联网连接到内联网 Web 服务服务器,我们需要扩大视野。
根据我的经验,解决这种情况的最佳且简单的方法可能是:
- 编写服务器端 Web 服务来代理请求并返回结果
- 编写服务器端代理页面
我喜欢编写一个简单且最小的服务器端网页,只是为了使用 Web 服务并返回调用的答案。 参数必须通过 post/get 调用传递到此类页面,并且结果页面必须包含适当的字段来包含结果。
为什么我更愿意这样做? 因为,通过服务器端最少的代码行,我还可以向客户提供测试对 WS 的调用是否正确运行的可能性 一些参数由客户即时决定,并在浏览器上的 html 页面中查找结果。
对我来说,在服务器端创建代理、在客户端使用它并让客户自己测试它是正确的折衷方案。
安全问题?不好了。它们完全取决于您添加代理页面的 Web 服务器的安全性。
这个解决方案也足够灵活,可以用于:java、c#、nodejs、php、perl……
因此,我拥有哪种类型的网络服务器绝对不重要:有时,唯一的词“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('<em>').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('</em>').css('cursor', 'auto');
});
};
<pre><code>......
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;');
}
});
</code></pre>
通过这种方式,我只需使用 javascript 和 Promise 技术就克服了服务器端知识的缺乏: 如果最终用户单击验证按钮,则通过代理页面调用 ws,否则会发生相同的操作,如果 ws 回答正常,则流程的其余部分可以正常执行 对沙巴一无所知。
这就是大家
关于javascript - 使用 SABA 的 Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26440590/