第一章 服务器端javascript XSJS
按照我们以往开发应用的经验,有客户端开发和服务器端开发。客户端开发在HANA XS应用开发里可以使用SAPUI5,一个完全运行在客户端的JS框架。那么我们也需要开发服务器端逻辑。HANA有SQLScript,但是它没法完全承担起服务器端开发的任务,不然O记也不需要JAVA,所有的应用都用PL/SQL好了。HANA XS应用的服务器端开发语言,依然是javascript。SAP选择了Mozilla SpiderMonkey https://developer.mozilla.org/en/docs/SpiderMonkey 作为服务器端JS的虚拟机。不知道为什么没有选择google的V8。SAP选择SJ作为服务器端编程语言,我觉得主要考虑还是因为它够轻量级。因为本身XS Engine就是一个轻量级的应用服务器,当然也要有一个足够轻量级的编程语言。
HANA XS的服务器端JS API参考手册在http://help.sap.com/hana/jsapi/index.html HANA XS的JS API的底层实现是由C/C++实现然后以JS API的方式暴露,似的开发人员能够用JS这种易用的语言调用。它能够与HANA XS引擎交互、直接访问HANA DB、处理HTTP请求等。
第二章 创建XSJS服务
本章只是让大家体验一下服务器端JS,有一个感性的认识。从HANA Studio,有一个创建选项:XS Javascript source file,这就是创建XS服务器端JS。
本章的示例代码为:
function
performMultiply(){
var
body =
''
;
var
num1 = $.request.parameters.get(
'num1'
);
var
num2 = $.request.parameters.get(
'num2'
);
var
answer;
answer = num1 * num2;
body = answer.toString();
$.response.setBody(body);
$.response.status = $.net.http.OK;
}
var
aCmd = $.request.parameters.get(
'cmd'
);
switch
(aCmd) {
case
"multiply"
:
performMultiply();
break
;
default
:
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody(
'Invalid Command: '
+aCmd);
}
我们可以看到,与当年写JAVA Servlet入门程序是很相像的,在服务器端解析http request请求,执行操作,然后构建http response文件。HANA XS JS的API是以美元符号作为前缀的。激活之后就可以打开浏览器运行测试了。
第三章 扩展XSJS服务
本章在上一章基础上演示了一个更复杂一点的XSJS代码。主要的功能是在计算乘法的基础上可以下载excel文件。示例代码如下:
$.import(
"sap.hana.democontent.epm.services"
,
"messages"
);
var
MESSAGES = $.sap.hana.democontent.epm.services.messages;
function
performMultiply(){
var
body =
''
;
var
num1 = $.request.parameters.get(
'num1'
);
var
num2 = $.request.parameters.get(
'num2'
);
var
answer;
answer = num1 * num2;
body = answer.toString();
$.response.setBody(body);
$.response.status = $.net.http.OK;
}
function
downloadExcel() {
var
body =
''
;
try
{
var
query =
'SELECT TOP 25000 \"PurchaseOrderId\", \"PartnerId\", \"CompanyName\", \"CreatedByLoginName\", \"CreatedAt\", \"GrossAmount\" '
+
'FROM \"sap.hana.democontent.epm.data::purchaseOrderHeaderExt\" order by \"PurchaseOrderId\"'
;
$.trace.debug(query);
var
conn = $.db.getConnection();
var
pstmt = conn.prepareStatement(query);
var
rs = pstmt.executeQuery();
body = MESSAGES.getMessage(
'SEPM_POWRK'
,
'002'
) + "\t
" + // PurchaseOrder ID
MESSAGES.getMessage('SEPM_POWRK', '003') + "
\t
" + // Partner ID
MESSAGES.getMessage('SEPM_POWRK', '001') + "
\t
" + // Company Name
MESSAGES.getMessage('SEPM_POWRK', '004') + "
\t
" + // Employee Responsible
MESSAGES.getMessage('SEPM_POWRK', '005') + "
\t
" + // Created At
MESSAGES.getMessage('SEPM_POWRK', '006') + "
\n
"; // Gross Amount
while (rs.next()) {
body += rs.getNString(1) + "
\t
" + rs.getNString(2) + "
\t
"
+ rs.getNString(3) + "
\t
" + rs.getNString(4) + "
\t
"
+ rs.getDate(5) + "
\t
" + rs.getDecimal(6) + "
\n
";
}
} catch (e) {
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody(e.message);
return;
}
$.response.setBody(body);
$.response.contentType = 'application/vnd.ms-excel; charset=utf-16le';
$.response.headers.set('Content-Disposition',
'attachment; filename=Excel.xls');
$.response.headers.set('access-control-allow-origin', '*');
$.response.status = $.net.http.OK;
}
var aCmd = $.request.parameters.get('cmd');
switch (aCmd) {
case "
multiply
":
performMultiply();
break;
case "
Excel":
downloadExcel();
break
;
default
:
$.response.status = $.net.http.INTERNAL_SERVER_ERROR;
$.response.setBody(MESSAGES.getMessage(
'SEPM_ADMIN'
,
'002'
, aCmd));
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
sap.ui.jsview(
"sapui5.xsjstest"
, {
getControllerName :
function
() {
return
"sapui5.xsjstest"
;
},
createContent :
function
(oController) {
var
multiplyPanel =
new
sap.ui.commons.Panel().setText(
"XS Service Test - Multiplication"
);
multiplyPanel.setAreaDesign sap.ui.commons.enums.AreaDesign.Fill);
multiplyPanel.setBorderDesign sap.ui.commons.enums.BorderDesign.Box);
var
layoutNew =
new
sap.ui.commons.layout.MatrixLayout({width:
"auto"
});
multiplyPanel.addContent(layoutNew);
var
oVal1 =
new
sap.ui.commons.TextField(
"val1"
,{tooltip:
"Value #1"
, editable:
true
});
var
oVal2 =
new
sap.ui.commons.TextField(
"val2"
,{tooltip:
"Value #2"
, editable:
true
});
var
oResult =
new
sap.ui.commons.TextView(
"result"
,{tooltip:
"Results"
});
var
oEqual =
new
sap.ui.commons.TextView(
"equal"
,{tooltip:
"Equals"
, text:
" = "
});
var
oMult =
new
sap.ui.commons.TextView(
"mult"
,{tooltip:
"Multiply by"
, text:
" * "
});
//Attach a controller event handler to Value 1 Input Field
oVal1.attachEvent(
"liveChange"
,
function
(oEvent){
oController.onLiveChangeV1(oEvent,oVal2); });
//Attach a controller event handler to Value 2 Input Field
oVal2.attachEvent(
"liveChange"
,
function
(oEvent){
oController.onLiveChangeV2(oEvent,oVal1); });
layoutNew.createRow(oVal1, oMult, oVal2, oEqual, oResult );
return
multiplyPanel;
}
});
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
onLiveChangeV1:
function
(oEvent,oVal2){
//To-Do: Insert Service Call to XSJS Service
var
aUrl =
'../../../services/Example1.xsjs?cmd=multiply'
+
'&num1='
+escape(oEvent.getParameters().liveValue)+
'&num2='
+escape(oVal2.getValue());
jQuery.ajax({
url: aUrl,
method:
'GET'
,
dataType:
'json'
,
success:
this
.onCompleteMultiply,
error:
this
.onErrorCall });
},
onLiveChangeV2:
function
(oEvent,oVal1){
//To-Do: Insert Service Call to XSJS Service
var
aUrl =
'../../../services/Example1.xsjs?cmd=multiply'
+
'&num1='
+escape(oVal1.getValue())+
'&num2='
+escape(oEvent.getParameters().liveValue);
jQuery.ajax({
url: aUrl,
method:
'GET'
,
dataType:
'json'
,
success:
this
.onCompleteMultiply,
error:
this
.onErrorCall });
},
onCompleteMultiply:
function
(myTxt){
var
oResult = sap.ui.getCore().byId(
"result"
);
if
(myTxt==undefined){ oResult.setText(0); }
else
{
jQuery.sap.require(
"sap.ui.core.format.NumberFormat"
);
var
oNumberFormat = sap.ui.core.format.NumberFormat.getIntegerInstance({
maxFractionDigits: 12,
minFractionDigits: 0,
groupingEnabled:
true
});
oResult.setText(oNumberFormat.format(myTxt)); }
},
onErrorCall:
function
(jqXHR, textStatus, errorThrown){
sap.ui.commons.MessageBox.show(jqXHR.responseText,
"ERROR"
,
"Service Call Error"
);
return
;
}
|