Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

第一章 服务器端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就是一个轻量级的应用服务器,当然也要有一个足够轻量级的编程语言。

110

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请求等。

25

第二章 创建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));

}

首先是import功能。这与JAVA没有什么两样。我们可以创建XSJS库文件以便被其它程序使用。import第一个参数书库文件的位置,第二个参数为库文件的名字。我们可以从HANA资源库看到这个库文件。

113

它里面的内容是一些编写好的function,比如 function getMessage(messageClass,messageNumber,p1,p2,p3,p4)

之后我们可以为这个库文件创建一个别名,如示例代码MESSAGES,然后以这个别名调用库文件内的函数。

代码里第二个值得主义的部分是对HANA数据库的操作。虽然语法类JDBC/ODBC,但是数据并不需要像JDBC调用那样经过网络传递,而是直接在HANA内部进行。

最后是对HTTP response的设置,使得客户端可以下载Excel文件。

第四章 从客户端调用XSJS服务


本章无非是利用SAPUI5(其实用不用都可以)构建一个用户界面,然后调用后端的XSJS文件获得结果。如果在AJAX刚开始流行时写过一点JS代码的相比都能想象得到是怎样的逻辑:在UI控件上设置相关事件和事件相应的函数;在函数里编写异步服务器端请求代码;获得结果的勾子函数用来展示数据。 只不过这一切用SAPUI5来实现罢了。

我们这里要实现的是两个textfield输入乘数与被乘数,在用户输入数值时立即计算并显示出结果。

我们首先创建新的SAPUI5视图和对应的引导文件html。 因为我们要响应控件的事件了,所以这次要在controller里写一些代码

view

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;

}

});

大部分代码都是在创建UI控件,只有下面一小部分真正是核心:对控件设置事件以及事件的响应函数。这里面oController就是该视图对应的控制器,用onLiveChange?函数响应textfield值变化这个事件。

Controller

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;

}

onLiveChangeV?本身并不是函数名,而是属性,但是由于javascript本身的语言特色,函数也可以是属性,了解如何用JS实现面向对象编程的对这样稍显怪异的语法结构不会陌生。

而对xsjs的调用利用了JQuery的API,里面成功与失败分别赋予了两个勾子函数,用来分别响应对服务器调用的成功与失败。

需要说明的是,在成功的方法里,我们可以看到sap.ui.getCore()方法可以获得UI上的控件,之后可以对其进行操作。

本章的内容其实跟HANA XS无关,甚至于SAPUI5关系都不大。这是多年以前AJAX的基础技术演示。如果对掌握这部分内容有困难的同学,还是先去google百度一下AJAX吧。

第五章 调试XSJS


这与在eclipse里调试其它代码没什么大的不同,只是要满足一些前提条件。

首先要保证HANA XS引擎的debug配置激活了,而且要配置一个端口用来监听debug session。

114

之后在eclipse里配置一个XSJS debug,指定服务器host和debug监听端口

26

最后,我们要获得连接HANA XS引擎的session ID。这存在于HTTP请求的cookie里。所以可以通过Chrome自带的developer tool获得xsSessionID

35

之后,当我们在eclipse里启动debug的时候会弹出窗口,让我们选择要debug的session,这个时候选择你在上一步获得的session即可。

由此可见,debug是很危险的,SAP不建议在生产系统做。我想,我们可以很容易的通过客户端工具篡改xsSessionID然后启动debug来获得其他用户权限的运行结果。

到此第五周的课程就结束了。还有一周,整个课程就结束了。下一周是HANA XS高级开发特性。为最后的考试做好准备吧。