AWS MVC 詳解


 

  由於新工作是在AWS PaaS平台上進行開發,為不耽誤工作,先整理一下AWS MVS的使用規范,快速上手。對AWS PaaS平台的相關介紹留到以后再來補充。本文幾乎是對官方學習文檔的整理,有遺漏的后補。

1.簡介

  AWS MVC(Model-View-Controller),輕量級、高性能,是開發AWS App的標准框架,同時AWS PaaS自身也是基於它開發。與傳統開源的Spring MVC、Strusts2相比:

  • 清晰、干凈、請求驅動(請求-響應)的輕量級Web編程框架
  • 學習難度遠小於Spring MVCStrusts2
  • No ServletNo JSPJust J2SE,更容易的開發調試和問題追蹤
  • 與AWS平台架構兼容的會話安全、DAO、I18N國際化、日志、審計和SLA告警機制
  • 沒有值棧、OGNL表達式、標簽庫等增加代碼復雜度和性能下降的架構缺陷
  • 優於Strusts2的注解編程和方法攔截,能直接根據注解綁定Request參數,更簡潔
  • 對處理結果是HTML、JSON、XML數據結構和錯誤碼的統一處理,避免業務架構缺陷
  • 提供了一套基於JQueryJQuery Mobile的AWS UI庫,針對企業級需求進行了增強封裝
  • 內核采用了NIO通信和多線程池化管理,能夠充分對計算資源的擴容做出適應,實現縱向擴展(Scale Up)
  • 為多個集群節點提供自我發現和自我糾正能力,簡化部署和運維,輕松實現彈性的橫向擴展(Scale Out)

特點:基於請求驅動,使用了前端控制器模式設計,再根據請求映射規則分發給相應的后端邏輯控制器(動作/處理器)進行處理

上圖,前端控制器(AWS Web Server / Front Controller)和后端處理控制(AWS App Server / Controller)是AWS MVC的核心通信框架,黃色區域(視圖組裝、模型、模版)寫業務邏輯,元素描述:

AWS Web Server 安裝有AWS Portal的標准Servlet容器,例如:Tomcat、WebLogic
AWS App Server 安裝有AWS Server的應用服務器,所有的業務邏輯在這里處理
Servlet 前端控制器 接收所有來自用戶的請求,封裝后轉發給AWS App服務器
后端處理控制器 通過注解攔截到方法,綁定邏輯處理程序
View視圖組裝 實現業務邏輯,返回處理的結果
Model模型 資源處理對象,如處理邏輯、對象、國際化、Dao處理、緩存
Template模版 基於靜態模版的渲染,處理成動態頁面結果

AWS MVC編程框架的主要組成部分:

  • 提交請求(submit)
  • 前端參數解析
  • 后端控制器(controller)
  • 業務對象封裝(ModelBean)
  • DAO封裝
  • Cache緩存
  • View視圖(返回結果)
  • 頁面模版渲染(Template)

其它(略):提高生產環境下的SLA服務可用性;應用的分發、安裝和卸載;對計算資源的擴容做出適應,實現縱向擴展(Scale Up)、獲得線性的橫向擴展(Scale Out)

2. 框架詳解

2.1 提交請求

AWS MVC基於Command命令請求驅動,約定5類常見url請求地址,都可以通過GET/POST提交

url 類型 說明
./w text/html (web)-請求結果一定是普通Web頁面數據時
./jd application/json (json data)-請求結果一定是ResponseObject Json
./xd application/xml (xml data)-請求結果一定是ResponseObject XML
./df application/octet-stream(成功)
application/json(失敗)
(download file)-文件下載流,如下載失敗或權限校驗不通過,返回Json處理結果
./uf application/json (upload file)-文件上傳流,返回Json處理結果

測試:啟動完本地AWS服務,瀏覽器輸入請求url:http://localhost:8088/portal/r/w?cmd=API_BENCHMARK_TEST&p=Hello AWS

說明

  1.8088是安裝AWS開發服務的默認Web端口號

  2./portal/是默認的Web App根名

  3.返回結果:“Hello AWS”,如下:

·Web可靠性編程習慣

  任何請求在極端環境或服務故障時都會發生錯誤。如果在瀏覽器背后(如一個Ajax請求)發送的HTTP返回一個特定數據結構或操作狀態值,那么AWS MVC會要求你在Java代碼使用ResponseObject對象進行封裝,並在前端對result進行檢查,只有當resultok時從data中讀取結果,否則應該檢查errorCodemsg項,並處理該異常(如提醒操作者或其他操作)。模擬一個停機故障:關閉AWS服務,但保持Web服務的正常運行,在瀏覽器中輸入以下URL請求:http://localhost:8088/portal/r/jd?cmd=API_BENCHMARK_TEST&p=Hello AWS

  說明

  1.使用./jd請求一個json數據結果,模擬加載ajax數據

  2.獲得了非預期的“Hello AWS”

  {
  result: "error",
  msg: "AWS Instance Server連接失敗!(590)"
  }

result值類型

  • ok(操作成功)
  • error(服務端發生錯誤,錯誤描述在msg項)
  • warning(服務端發生警告,警告描述在msg項)
 3.查看結果:↓

  

默認編碼字符集:utf-8

常規請求必須參數

  • sid(用戶會話)
  • cmd(請求指令。命名規范:前綴為該應用的Id,后面是動作名,中間以下划線分割,區分大小寫

  

Web層配置文件

  每個AWS App的Web資源被獨立的定義在webapp根目錄apps/%AppId%下。如果該應用需要cmd處理,至少應定義一個接參配置文件,並建議命名為action.xml如果使用AWS自帶的Developer開發工具,該配置文件可忽略,AWS Developer會自動根據Controller類同步構建該配置)。配置文件存為 UTF-8 NO BOM,格式為一個或多個符合Schema規范、以action(不區分大小寫)開頭、后綴為xml的文件。action.xml位置及內容示例:

  

<?xml version="1.0" encoding="utf-8"?> <aws-actions> <cmd-bean name="%AppId%_xxx1"> <param name="p1" /> </cmd-bean> <cmd-bean name="%AppId%_xxx2"> <param name="p1" /> </cmd-bean> <cmd-bean name="%AppId%_xxx3"> <param name="p1" type="body"/> </cmd-bean> </aws-actions>

實際項目中配置

 cmd-bean的type屬性:

  • type不配置時,該參數的值來自請求中查詢參數或者application/x-www-form-urlencoded類型內容中請求參數
  • type=body時,該參數的值來自請求內容application/xml、application/json等類型的值,Controller將接收到請求內容的字符串值
  • type=cookie時,該參數的值來自請求內容的cookie,Controller將接收到對應namecookie
  • type=header時,該參數的值來自請求內容的header,Controller將接收到對應nameheader

2.1.1 Form Submit提交

  普通表單提交處理方式,包括HTML的form提交和js提交。如下模擬一個數值運算場景,由瀏覽器提交兩個數值和運算類型,經過前端控制器傳參和后端控制器的接參,最終抵達邏輯區

a) HTML提交:

<!doctype html> <html> <head> <meta charset="UTF-8"> <title>數據計算</title> <!-- JQuery --> <script type="text/javascript" src="../commons/js/jquery/scripts/jquery.js"></script> <!-- AWS UI --> <link rel="stylesheet" type="text/css" href="../commons/css/awsui.css"> <script type="text/javascript" src="../commons/js/awsui.js"></script> </head> <body> <form id="editForm" method="post" action="./jd?sid=<#sid>&cmd=%AppId%_calculation"> <table class="awsui-ux"> <tr> <td class="awsui-ux-title">計算</td> <td class="required"> <input id="number1" name="number1" class="awsui-textbox" /> <select id="sign" name="sign" class="awsui-select"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> <input id="number2" name="number2" class="awsui-textbox" /> <span> = </span> <input id="results" name="results" class="awsui-textbox" /> </td> </tr> <tr> <td class="awsui-ux-title" colspan="2" style="text-align: center; "> <span id="submitBtn" class="button blue">提交</span> </td> </tr> </table> </form> </body> </html>
注:上述源碼中,<#sid>在實際運行中由實際的用戶會話Id替代

b) JavaScript提交:

$('#submitBtn').click(function(e) { // 提交表單 $('#editForm').submit(); });

c) 前端傳參配置(Web層action.xml配置文件)

<?xml version="1.0" encoding="utf-8"?> <aws-actions> <cmd-bean name="%AppId%_calculation"> <param name="number1" /> <param name="number2" /> <param name="sign" /> </cmd-bean> </aws-actions> 
  • 聲明%AppId%_calculation命令,%AppId%是你實際的應用Id
  • 該命令接收number1,number2,sign三個參數

d) 后端接參處理

式1(推薦)

@Mapping("%AppId%_calculation") public String calculation(UserContext me, int number1, int number2, @Param(defaultValue = "+")String sign) { TestWeb web = new TestWeb(me); return web.calculation(number1, number2, sign); } 
  • 顯示定義與變量名匹配的方法參數
  • UserContext是AWS MVC內置對象,獲得當前操作者上下文信息
方式2
@Mapping("%AppId%_calculation") public String calculation(UserContext me, RequestParams params) { // 參數接收 int number1 = params.getInt("number1"); // 獲取整數類型 int number2 = params.getInt("number2"); // 獲取整數類型 String sign = params.get("sign", "+"); // 獲取字符串類型,第二個參數為默認值,以下方式相同 // Boolean bool = params.getBoolean('paramsName'); // 獲取Boolean類型 // Double number = params.getDouble('paramsName'); // 獲取浮點型參數 TestWeb web = new TestWeb(me); return web.calculation(number1, number2, sign); } 
  • 不定義方法參數,動態從RequestParams對象中讀取變量
  • 這種方式可以讓你的代碼更靈活,但不利於重構

e) View層邏輯處理

public class TestWeb extends ActionWeb { public TestWeb() { } public TestWeb(UserContext ctx) { super(ctx); } public String calculation(int number1, int number2, String sign) { ResponseObject ro = ResponseObject.newOkResponse(); // 處理邏輯 // ro.put("newNum",newNum); return ro.toString(); } }

2.1.2 Ajax請求

1)AWS在JQuery ajax基礎上對常用異步請求封裝,提供4類請求(request、load、post、get),並對底層進行了統一的處理,如異常攔截。方法說明:

  1.awsui.ajax.request

    a) 通過 HTTP 請求加載遠程數據,參考jQuery.ajax()。

    b) 參數:url,[settings]。分別是String,Object類型
    url:一個用來包含發送請求的URL字符串。
    settings:AJAX 請求設置。所有選項都是可選的。

  2.awsui.ajax.load

    a) 載入遠程 HTML 文件代碼並插入至 DOM 中。默認使用 GET 方式 - 傳遞附加參數時自動轉換為 POST 方式

    b) 參數:url,[data,[callback]]。類型:String,Map/String,Callback
    url:待裝入 HTML 網頁網址。
    data:發送至服務器的 key/value 數據。
    callback:載入成功時回調函數

  3.awsui.ajax.post

    a) 簡單POST 請求,成功可調用回調函數

    b) 參數:url,[data],[callback],[type]。類型:String,Map,Function,String
    url:發送請求地址。
    data:待發送 Key/value 參數。
    callback:發送成功時回調函數。
    type:返回內容格式,xml, html, script, json, text, _default

  4.awsui.ajax.get

    a) 簡單GET 請求。請求成功時可調用回調函數

    b) url,[data],[callback],[type]。類型:String,Map,Function,String
    url:發送請求地址。
    data:待發送 Key/value 參數。
    callback:發送成功時回調函數。
    type:返回內容格式,xml, html, script, json, text, _default。

  5,awsui.ajax.ok

    a) 驗證是否為返回狀態是否為成功

    b) data:ajax請求后的返回對象

  6.awsui.ajax.responseObject

    a)驗證是否為ResponseObject對象

    b)data:字符串或對象。

  7.awsui.ajax.alert

    a)彈出請求提示消息

    b)data, model, callback 。類型:Object, boolean,Function
    data: 異步請求返回對象。
    model: 消息提示框的展示模式,是否為模態。
    callback:彈出消息提示后回調函數

示例代碼

awsui.ajax.request 示例

awsui.ajax.request({
    type: "POST", url: "./jd?sid="+sid+"&cmd=%AppId%_calculation", data: "number1=15&number2=1032&sign=+", ok : function(r) { //請求處理成功 }, err : function(r){ //請求處理錯誤 } }); 

awsui.ajax.load 示例

awsui.ajax.load("./jd?sid="+sid+"&cmd=%AppId%_calculation", { number1: 15, number2: 1032, sign: '+' }, function(data){ awsui.ajax.alert(data, true, function(){ alert('callback'); }); }); 

awsui.ajax.post 示例

awsui.ajax.post("./jd?sid="+sid+"&cmd=%AppId%_calculation", { number1: 15, number2: 1032, sign: '+' }, function(data) { awsui.ajax.alert(data, true, function(){ alert('callback'); }); }, 'json'); 

awsui.ajax.get 示例

awsui.ajax.get("./jd?sid="+sid+"&cmd=%AppId%_calculation", { number1: 15, number2: 1032, sign: '+' }, function(data) { if(awsui.ajax.responseObject(data)) awsui.ajax.alert(data, true, function(){ alert('callback'); }); }, 'json'); 

awsui.ajax.ok 示例

if(awsui.ajax.ok(data)) alert(data['msg']); 

awsui.ajax.responseObject 示例

if(awsui.ajax.responseObject(data)) awsui.ajax.alert(data, true, function(){ alert('callback'); }); 

awsui.ajax.alert 示例

awsui.ajax.alert(data, true, function(){ alert('callback'); }); 

2)后端接參

@Mapping("%AppId%_calulation") public String calculation(UserContext me, int number1, int number2, String sign) { TestWeb web = new TestWeb(me); return web.calculation(number1, number2, sign); } 

3)View層邏輯處理

public class TestWeb extends ActionWeb { public TestWeb() { } public TestWeb(UserContext ctx) { super(ctx); } public String calculation(int number1, int number2, String sign) { ResponseObject ro = ResponseObject.newOkResponse(); // 處理邏輯 // ro.put("newNum",newNum); return ro.toString(); } } 

2.1.3 上傳文件

AWS容器對各資源提供沙箱管理,對文件讀寫提供了一套完善的DC(Doc Center)機制,文件必須通過DC處理器進行處理。AWS對文件上傳封裝了一個公用的組件,能夠滿足常用瀏覽器(IE8+, Firefox,Google Chrome,Safari,平板UC等)的文件上傳功能。

a)服務端插件注冊和聲明

注冊DCPluginProfile要聲明repositoryName(存放文件的根目錄名)和文件處理器(繼承com.actionsoft.bpms.server.fs.AbstFileProcessor)。

  • 有關DC開發詳細內容,參見《AWS 插件擴展開發參考指南》
  • 有關DC API操作(如讀、寫文件),參見aws-api-doc提供的DCAPI

b)客戶端調用

upfile是AWS UI封裝的通用文件上傳組件,采用雙核技術(IE8/IE9提供Flash模式,對支持HTML5的瀏覽器采用無插件模式)實現批量文件上傳、文件類型過濾、文件大小控制和上傳進度控制,對各類瀏覽器提供了較好的體驗支持。

  i)上傳組件的資源引用

<link rel="stylesheet" type="text/css" href="../commons/css/awsui.css"/> <script type="text/javascript" src="../commons/js/jquery/scripts/jquery.js"></script> <script type="text/javascript" src="../commons/js/awsui.js"></script> 

  ii)用JavaScript打開上傳對話框

<script type="text/javascript"> $(function(){ //myUpfile對象綁定upfile組件 $("#myUpfile").upfile({ sid: "<#sid>", // 會話ID appId: "com.actionsoft.apps.poc.plugin", // 應用ID groupValue: "dir1", // DC大類,建議變量規則 fileValue: "dir2", // DC小類,建議變量規則 numLimit: "2", //最多一次允許上傳幾個,0(無限制) filesToFilter : [["Images (*.jpg; *.jpeg; *.gif; *.png; *.bmp)","*.jpg; *.jpeg; *.gif; *.png; *.bmp"]], repositoryName: "myfile", // 該應用申請的DC名 done: function(e, data){ //事件回調函數 //上傳完成后,開始調用導入代碼 if (awsui.ajax.ok(data.result.data)) {//判斷請求是否執行成功 //可以調用公共方法處理提示信息 awsui.ajax.alert(data.result.data); //或者自行處理提示信息 //$.simpleAlert('文件上傳成功!'); // downloadURL var url = data.result.data.data.attrs.url; //如果定義了其他返回的屬性,也需要使用data.result.data.data.attrs調用 } else { // 上傳失敗,提示出錯誤信息 awsui.ajax.alert(data.result.data); } } }); }); </script> 

  iii)上傳按鈕的定義

<span id="myUpfile" class="button green" onclick="return false;">上傳</span> 

上述客戶端調用示例,也可從AWS企業應用商店安裝擴展插件概念驗證應用,所有源碼在src目錄下

c)參數說明

  • 屬性
Name Type Description Default
sid(*-必須) String 會話ID  
appId(*-必須) String 應用ID  
repositoryName(*-必須) String DC插件定義  
groupValue(*-必須) String 文件大類  
fileValue(*-必須) String 文件小類  
filesToFilter String var filter = [["Images (.jpg; .jpeg; .gif; .png; .bmp)",".jpg; .jpeg; .gif; .png; .bmp"]]; 不過濾,可上傳所有文件
sizeLimit number 文件大小限制 25*1024*1024(25M)
numLimit int 上傳個數限制 0(無限制)
  • 事件

 

Name Param Description
add e 事件;data(返回的數據) 文件被添加到上傳列表時觸發,當返回false時,可阻止上傳。
例如: //data.files 為上傳文件的數組
add:function(e, data){
     //data.files 為上傳文件的數組
     $.each(data.files, function(index, file) {
        // file.name 文件名稱 file.size 文件大小 file.type 文件類型
    }) if(size==0){ //空文件不允許上傳 return false;
} }
progress e 事件;data(返回的數據) 文件上傳中觸發
done e 事件;data(返回的數據) 單個文件上傳完畢后觸發
error e 事件;data(返回的數據) 單個文件上傳失敗后觸發。
可能是web服務器也可能是app服務器造成的失敗
complete   文件成功上傳結束后觸發

2.1.4 下載文件

下載DC倉庫內文件的url必須由DCContextgetDownloadURL()獲取。

  • 以下是獲取文件下載鏈接的Java示例

    // 構造下載附件的url鏈接 UserContext me = getContext(); String appId = "xxxxxx"; //該App Id名 String repositoryName = "orderFile"; //該App的DC倉庫根目錄 String groupValue = yearMonth; //一級目錄為年月,201402 String fileValue = orderId; //訂單Id String fileName = "order.jpg"; //文件名 DCContext context = new DCContext(me, SDK.getDCAPI().getDCProfile(appId, repositoryName), appId, groupValue, fileValue, fileName); result.put("url", context.getDownloadURL()); 
  • JavaScript示例

    window.open(url); // or window.location.href = url;

 

2.2 后端處理控制器

就這么簡單,提交的請求已經被AWS MVC傳輸至AWS應用層。

AWS MVC的后端控制器以@Controller注解到普通的Java類,並為該方法增加@Mapping("%Command%")注解即可。控制器會負責將前端cmd參數名與該Java方法的參數名進行匹配和賦值,完成攔截、綁定和執行過程。

下面是一個Controller示例

@Controller public class ABCController { // Test1 @Mapping("%AppId%_xxx1") public String apiTestHome(UserContext me, String p1) { return "Hi,p1="+p1; } //Test2 @Mapping("%AppId%_xxx2") public String apiInfo(UserContext me, String p2) { ABCWeb abc= new ABCWeb(me); return abc.getMainPage(p2); } } 

注解

控制器只負責攔截、綁定和執行cmd方法,對於該方法的具體實現應交給View層處理,不建議直接在Controller中完成邏輯處理。

注解 說明
@Controller 類注解。聲明該類是一個后端處理控制器
@Mapping 方法注解。聲明該方法將響應一個前端Web請求,參數值是該cmd值

默認每個請求必須含有sid的會話信息,如開發者要求在無session場景下執行服務端請求,可參考如下語法

@Mapping(value = "%AppId%_xxx3", session = false, noSessionEvaluate = "無安全隱患", noSessionReason = "用於MVC框架穩定性測試") 
  • value,cmd的名稱
  • session,是否攔截sessionId進行合法性校驗
  • noSessionEvaluate,對安全隱患做出評估說明
  • noSessionReason,設計該cmd的原因或功效

被標記為無session驗證的請求是非常不安全的,原因是AWS無法識別請求者身份。開發者應審慎評估該請求背后執行的邏輯規則,不會被用於惡意處理

參數映射

以下參數可以出現在方法參數中

參數 說明
UserContext對象類型 【可選】獲取AWS用戶會話對象
RequestParams對象類型 【可選】獲取請求參數,Key為變量名,Value為值
clientIp變量名 【可選】String類型。客戶端ip地址
responseType變量名 【可選】String類型。請求結果類型(W/JD/XD...)見Message常量
%變量名% 【可選】cmd的參數名,支持String、Integer、Boolean、Long、Double類型。變量的命名來自具體請求中提供的參數

package包結構命名建議

  • /model/ 存放modelBean類
  • /dao/ 存放DAO類
  • /cache/ 存放cache類
  • /web/ 存放view類
  • /util/ 存放util或service邏輯處理類

注意事項

第一次創建Controller類並進行調試時,需要編譯jar文件至該app的lib目錄下,否則可能會提示找不到cmd異常。這是一個設計缺陷,我們計划在時間充分的時候修復

下圖為實例:

 

2.3 View視圖

不建議直接在處理控制器中完成業務處理過程。

在AWS MVC框架中,View層負責實現具體的業務邏輯,組織處理結果。View提供客戶端用戶會話、身份及設備等信息,通過繼承ActionWeb,完成View的開發。

開發示例

public class ABCWeb extends ActionWeb { public ABCWeb (UserContext uc) { super(uc); } public String getMainPage(String p2) { return “Hi,p2=”+p2; } } 

異常處理

當操作發生錯誤時,框架將拋出uncheck異常(如AWSDataAccessException),如果你的邏輯沒有方案或需求去處理這個異常可以繼續向外拋出。

當操作發生參數非法、執行非法等常見View層處理邏輯場景時,建議拋出如下異常(詳細請參見異常處理章節)

  • AWSIllegalArgumentException 非法參數異常造成錯誤的訪問請求,對應400錯誤
  • AWSObjectNotFindException 資源未找到異常,對應404錯誤
  • AWSForbiddenException 訪問被拒絕異常,對應403錯誤

框架范圍之外的util或service層

如果業務處理邏輯相對復雜,建議將邏輯操作封裝成util類或service類

識別訪問者設備類型

通常你在為PC端瀏覽器的界面交互編程。如果需要你的程序能夠更好的服務於其他移動設備,可以調用UserContext.getDeviceType()方法獲取到當前用戶的設備類型。

  • LoginConst.DEVICE_PC PC桌面電腦
  • LoginConst.DEVICE_TABLET 平板電腦
  • LoginConst.DEVICE_MOBILE 智能手機

與View相關的常見開發

  • Server端開發
    • 模版渲染(HTML靜態文件+標簽)
    • ModelBean封裝
    • DAO封裝
    • Cache封裝
  • Web端開發
    • JavaScript
    • CSS
    • 熟悉portal/commons下的各種組件資源,如AWS UI、JQuery Mobile

2.3.1 HTML Document

  AWS MVC提供了頁面模版處理框架,通過定義模版變量和程序對變量的處理生成最終頁面內容。

  提交請求的響應結果通常是一個完整的HTML Document。在一些前端動態拼裝場景,局部DOM結構也可以被獨立的定義成模版文件。但有時局部DOM無需使用模版,直接由程序動態組裝。

  模版被存放在該應用安裝目錄的template/page下,通常以html或htm后綴結尾(命名區分大小寫)。除內容符合標准HTML、CSS、JavaScript規范外,模版標簽變量定義的規則是,將需要程序生成的部分以<#變量名>替換,最終由HtmlPageTemplate.merge()混合成用戶瀏覽器中的html內容。

如果該模版中出現的文字需要進行多語言處理,可以<I18N#變量名>定義,其中變量名是為該應用抽取的多語言配置項的Item的Key。

在View層程序中完成模版處理的示例

public class ABCWeb extends ActionWeb { public ABCWeb (UserContext uc) { super(uc); } public String getMainPage(String p2) { Map<String, Object> macroLibraries = new HashMap<String, Object>(); macroLibraries.put("page_title", "hello"); macroLibraries.put("p2", p2); macroLibraries.put("sid", getContext().getSessionId()); return HtmlPageTemplate.merge("%AppId%", "模版文件名", macroLibraries); } } 

HTML模板示例

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title><#page_title></title> <!-- 在JS中使用變量,如果需要 --> <script> var sid = '<#sid>'; </script> </head> <body> <form action="./w" method=post name=frmMain > <!-- 在HTML中使用變量,如果需要 --> p2的值是<b><#p2></b> </form> </body> </html> 

模版文件默認編碼字符集

utf-8

HTML模版資源引用范圍

  • AWS平台Web目錄commons/下的js、css、圖片等公共資源
  • AWS平台Web目錄apps/%appId%/下自定義的資源(appId為本應用的id)
  • 建議使用相對路徑,如../apps/xxx、../commons/xxx

2.3.2 非HTML結果

一些來自前端Ajax操作或服務請求通常需要響應一個結構化數據:

  • 一個操作結果是否成功
  • 一個被封裝的數據結構

類型支持:

  • JSON
  • XML

ResponseObject

com.actionsoft.bpms.commons.mvc.view.ResponseObject

ResponseObject對象是AWS為開發者提供的一個通用數據對象封裝,用於封裝一個結構化處理結果。ResponseObject支持三種處理狀態:

常量 說明
ResponseObject.SUCCESS ok 被成功處理。對應AWS UI中simpleAlertd的ok或info提示
ResponseObject.WARNING warning 操作發生警告。對應AWS UI中simpleAlertd的warning提示
ResponseObject.ERROR error 操作發生錯誤。對應AWS UI中simpleAlertd的error提示

狀態值可在返回結果的result項檢查,這是一個必須結構

msg-信息

當處理成功或發生失敗時,應該將進階的信息反饋給調用者。

//success msg return ResponseObject.newOkResponse("a訂單被取消").toString(); //或者 ResponseObject ro=ResponseObject.newOkResponse(); ro.msg("a訂單被取消"); return ro.toString(); //warning msg return ResponseObject.newWarnResponse("a訂單已經發出").toString(); //或者 ResponseObject ro=ResponseObject.newWarnResponse(); ro.msg("a訂單已經發出"); return ro.toString(); //error msg return ResponseObject.newErrResponse("a訂單取消失敗,原因是xxxx").toString(); //或者 ResponseObject ro=ResponseObject.newErrResponse(); ro.msg("a訂單取消失敗,原因是xxxx"); return ro.toString(); 

補充信息可在返回結果的msg項檢查,這是一個附加結構

data-數據

以key/value形式由開發者自定義,value可以是一個簡單Java對象也可以是一個集合對象。

Map<String, Object> orderDetails = new HashMap<>(); orderDetails.put("orderId", "001"); orderDetails.put("customerId", "999"); orderDetails.put("customerName", "Actionsoft"); orderDetails.put("amount", Double.valueOf("980.01")); ResponseObject ro = ResponseObject.newOkResponse(); ro.put("enabled", true); ro.put("orderDetails", orderDetails); return ro.toString(); 

數據可在返回結果的data項檢查,這是一個附加結構

處理成JSON

默認ResponseObjecttoString()將數據結構拼裝成JSON串。

return ro.toString(); 

含有狀態信息的JSON結構

{
    data: {
        enabled: true,
        orderDetails: {
            amount: 980.01,
            customerName: "Actionsoft",
            customerId: "999",
            orderId: "001"
        }
    },
    msg: "",
    result: "ok"
}
return ro.toDataString(); 

只有數據的JSON結構

{
    enabled: true,
    orderDetails: {
        amount: 980.01,
        customerName: "Actionsoft",
        customerId: "999",
        orderId: "001"
    }
}

處理成XML

return ro.toXML(); 

含有狀態的XML Document片段

<result type="ok" errorCode="" msg="" /> 

數據來自文件系統

如果你的Java程序讀取本地文件系統的文件,建議文件名和內容強制以utf-8讀和寫。這樣做的原因是中文系統的Window默認是936字符集(可以使用chcp命令查看和設置),而大部分OS Server以utf-8進行編碼。

如果程序強制以utf-8處理文件,當AWS PaaS在部署一段時間后,客戶希望在Windows和Linux之間做遷移時,能夠確保用戶數據編碼格式的一致性。

 

2.4 業務對象封裝

與其他MVC開發框架一樣,編寫出結構清晰的程序代碼,需要對業務實體對象進行屬性封裝(概念如POJOJavaBean)。

AWS MVC提供了設計業務實體對象的父類ModelBeanIModelBean接口,采用ModelBean封裝的業務實體對象,還有以下優勢:

  • 提供方法轉換成JSON數據結構
  • 提供方法轉換成XML數據結構
  • 作為DAO處理的實體表結構對象
  • 作為集群Cache的數據結構對象

TestModel開發示例

public class TestModel extends ModelBean implements IModelBean { private String id; private String f1; private double f2; public TestModel() { } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getF1() { if (f1 == null) { f1 = ""; } return f1; } public void setF1(String f1) { this.f1 = f1; } public double getF2() { return f2; } public void setF2(double f2) { this.f2 = f2; } } 

IModelBean接口聲明

/** * AWS MVC框架中,表示實體業務對象接口 */ public interface IModelBean extends Serializable { /** * 將當前對象轉換成json處理對象 */ public JSONObject toJsonObject(); /** * 將當前對象轉換成json串 */ public String toJson(); /** * 將當前對象轉化成XML片段 */ public String toXML(); } 

2.5 DAO封裝

  AWS的DAO基於對JDBC的直接封裝,與當今流行的Hibernate、iBATIS相比,去除了O/R映射關系的直接依賴,並借鑒了Apache DBUtils設計思想,只在需要的場景完成O/R Mapping。

  采用AWS MVC的DAO優勢如下:

  • 代碼簡單、直接,性能高
  • 無需拼寫SQL語句,自動提供表查詢、刪除和更新操作
  • 屏蔽分頁技術,自動適應不同數據庫的物理分頁
  • 提供自定義的RowMapper,將JDBC對象轉換成業務實體對象(ModelBean
  • 提供操作復雜數據庫操作的DBSql工具類
  • 所有操作受控於AWS SLA的質量和性能監控、告警

DaoObject類和方法介紹

Dao(Data Access Object)是一個設計模式,它是對數據訪問的一種抽象。com.actionsoft.bpms.commons.mvc.dao.IDaoObject是AWS設計的數據庫訪問接口,DaoObject是實現了IDaoObject接口用於訪問AWS本地數據庫的抽象父類,該類對單主鍵數據庫表的查詢/更新/刪除等常規操作提供了實現。

TestDao開發示例

  1. 繼承ModelBean,實現業務實體對象
  2. 繼承DaoObject,實現Dao處理對象

    public class TestDao extends DaoObject<TestModel> { public TestDao() { } /** * 插入一條測試記錄 */ @Override public int insert(TestModel model) throws DataAccessException{ model.setId(UUIDGener.getUUID()); String sql = "INSERT INTO " + entityName() + "(ID,F1,F2)VALUES(:ID,:F1,:F2)"; Map<String, Object> paraMap = new HashMap<>(); paraMap.put("ID", model.getId()); paraMap.put("F1", model.getF1()); paraMap.put("F2", model.getF2()); return DBSql.update(sql, paraMap); } /** * 更新一條測試記錄 */ @Override public int update(TestModel model) throws DataAccessException{ if (UtilString.isEmpty(model.getId())) { throw new DataAccessException("Method getId() Does Not Allow Empty!"); } Map<String, Object> paraMap = new HashMap<>(); paraMap.put("F1", model.getF1()); paraMap.put("F2", model.getF2()); // 不需要寫sql,可調用基類封裝的update方法 return update(model.getId(), paraMap); } /** * 封裝測試 * * @param id * @param f2 * @return */ public int updateF2(String id, double f2) throws DataAccessException{ Map<String, Object> paraMap = new HashMap<>(); paraMap.put("F2", f2); return update(id, paraMap); } /** * 封裝DBSql測試 * * @return */ public long count() { return DBSql.getLong("SELECT COUNT(ID) AS C FROM " + entityName(), "C"); } /** * 封裝DBSql測試 * * @param f2 * @return */ public List<TestModel> queryByF1(String f1) { return query("F1=?", f1).orderBy("F2").desc().list(); } /** * 該Dao實現的表名稱 */ @Override public String entityName() { return "TEST_DAO"; } /** * 構建該Dao從一條記錄轉換成對象的映射對象 */ @Override public RowMapper<TestModel> rowMapper() { return new Mapper(); } /** * TestDao Mapper */ private class Mapper implements RowMapper<TestModel> { public TestModel mapRow(ResultSet rset, int rowNum) throws SQLException { TestModel model = new TestModel(); try { model.setId(rset.getString("ID")); model.setF1(rset.getString("F1")); model.setF2(rset.getDouble("F2")); } catch (Exception e) { e.printStackTrace(); } return model; } } } 

    異常處理

    當操作發生錯誤時,框架將拋出uncheck異常(如AWSDataAccessException),如果你的邏輯沒有方案或需求去處理這個異常可以繼續向外拋出。

當操作發生參數非法、執行非法等常見Dao處理邏輯場景時,建議拋出如下異常(詳細請參見異常處理章節)

  • AWSIllegalArgumentException 非法參數異常造成錯誤的訪問請求,對應400錯誤
  • AWSObjectNotFindException 資源未找到異常,對應404錯誤
  • AWSForbiddenException 訪問被拒絕異常,對應403錯誤

默認編碼字符集

utf-8

事務處理與資源釋放

Spring MVC自動接管了事務與資源釋放,這是非常棒的編程體驗。為提高性能,目前AWS DAO框架未接管JDBC事務和自動完成Connection釋放。

當你的程序需要事務支持時,可以遵循標准的JDBC編程規范,對Connection對象進行事務的開啟、回滾或提交。

如果你的程序獲得了一個新的Connection(如通過DBSql.open()),那么最終需要你的代碼通過DBSql.close()釋放這個連接。

物理表

建議使用AWS的BO模型設計和維護你的物理表結構,如果某些表必須由自己的sql創建(不推薦),那么需要遵循App開發規范中約定的表名前綴和sql安裝/升級腳本規范。

數據庫連接池

AWS MVC的數據庫連接池使用了tomcat-jdbc,相關高級參數調優,可修改對應AWS安裝目錄bin/conf/db_pool.properties文件。

DBSql類和方法介紹

com.actionsoft.bpms.util.DBSql是和AWS數據庫交互的工具類,它基於PreparedStatement實現了數據庫的查詢、插入、更新、批處理,DBSql一般用於DaoObject中。

  • get方法用於簡單類型查詢
  • query方法用於自定義復雜查詢
  • update方法用於數據庫的更新/插入/刪除
  • batch方法用於批處理
  • open/close數據庫連接/釋放
  • 其它工具方法
// 查詢單個字段 String value_a = DBSql.getString("select a from table_test where id=?", new Object[]{"id1"}); // 查詢多個字段 Map<String,Object> value_map = DBSql.getMap("select a,b,c from table_test where id=?", "id1"); // 查詢返回自定義對象,MyBean是java類 List<MyBean> list = DBSql.query("select a,b,c from table_test where id=?", new RowMapper<MyBean>() { @Override public MyBean mapRow(ResultSet rs, int rowNum) throws SQLException { MyBean mybean = new MyBean(); mybean.setA(rs.getString("a")); return mybean; } }, "id1"); 

詳細請參見aws-api-docDBSql

 

2.6 Cache緩存

AWS MVC的Cache框架支持本地緩存和集群緩存,可以通過擴展AWS平台的Cache插件(Plugin)實現自己的緩存對象。

有關Cache開發詳細內容,參見《AWS 插件擴展開發參考指南》

 

3 異常處理框架

  AWS MVC框架的異常處理過程如下所示

異常處理框架

在上圖中,請求者(用戶或服務API)被前端控制器封裝成指令並傳輸至AWS服務器,當圖中紅色、橙色和黃色區域異常發生后,由AWS的頂層異常攔截器捕獲,向請求者返回錯誤消息。

在這個章節中,你將了解如下內容:

  • 錯誤碼定義
  • 拋出異常
  • 處理異常

3.1 錯誤碼

  通過對錯誤碼定義,能夠簡單的幫助用戶或開發者識別和理解異常性質,錯誤碼與錯誤不是一對一關系,是錯誤類型的一種抽象代號。

  AWS的錯誤碼參照了HTTP狀態碼定義。錯誤碼以3位的數字代碼表達,所有錯誤碼首數字代表的一類錯誤。

首數字 說明
4 客戶端錯誤
5 服務端錯誤
7 服務可用性
8 配合限制和其他

  當請求返回了AWS非預期消息或錯誤時,除了提供錯誤碼,通常我們會根據具體的場景提供問題概要說明,如果是出錯類異常,詳細信息一定被記錄到AWS的error.log文件。

 

碼表

Code 描述 異常或發生場景
400 錯誤的參數請求(Bad Request)

通常當缺少必要參數,或者參數值格式不正確時,會返回該錯誤信息。此時可以查看相關文檔確認每個參數的格式是否正確。例如:執行啟動流程方法時,未提供processInstId參數
AWSIllegalArgumentException

* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
401 未授權被拒絕(Unauthorized)

當用戶提供了無效的session,或者請求的鑒權結果不正確時,會返回該錯誤信息。
目前只適用於SOAP/REST API的Web層封裝的錯誤代碼,不適用於服務器端異常處理

當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
403 訪問被拒絕(Forbidden)

該請求是有效的,但操作是被禁止且不應該再次嘗試時,會返回該錯誤信息。例如:要執行的任務實例已結束
AWSForbiddenException

* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
404 找不到資源對象(Not Find Resource)

當用戶試圖訪問不存在的資源時,會返回該錯誤信息。例如:要執行的任務實例已不存;賬戶不存在
AWSObjectNotFindException
405 請求方法不允許(Method Not Allowed)

使用了不支持的請求方法去操作資源時,會返回該錯誤信息。例如:使用GET請求一個POST操作
* 目前只適用於REST API的Web層封裝的錯誤代碼,不適用於服務器端異常處理
408 資源請求超時(Request Timeout)

請求超出了等待時間,會返回該錯誤信息。例如:在調用AWS的SOAP或REST服務,連接至AWS服務器超時
* 目前只適用於SOAP/REST API的Web層封裝的錯誤代碼,不適用於服務器端異常處理
500 內部錯誤(Internal Server Error)

當服務器執行請求過程中,遇到內部處理錯誤時,會返回該錯誤信息。遇到這種錯誤,請檢查AWS的錯誤日志,及時與我們聯系
AWSException
所有繼承該異常子類,未實現錯誤號的異常(getAPIErrorCode())
所有JDK或非AWS異常拋出,被系統捕獲的

* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
520 引擎錯誤(Engine Error)

當服務器執行請求過程中,遇到流程引擎、表單引擎等引擎類錯誤時,會返回該錯誤信息。遇到這種錯誤,請檢查AWS的錯誤日志,及時與我們聯系
AWSEngineException
AWSExpressionException
521 傳輸轉換錯誤(Transfer Error)

當服務器執行請求過程中,遇到導入導出或格式轉換錯誤時,會返回該錯誤信息。遇到這種錯誤,請檢查AWS的錯誤日志,及時與我們聯系
AWSTransferException
530 應用容器錯誤(App Container Error)

當服務器執行請求過程中,遇到PaaS應用容器類錯誤時,會返回該錯誤信息。遇到這種錯誤,請檢查AWS的錯誤日志,及時與我們聯系
AppContainerException
540 應用商店錯誤(AppStore Error)

當服務器執行請求過程中,遇到PaaS與AppStore相互處理過程中發生錯誤時,會返回該錯誤信息。遇到這種錯誤,請檢查AWS的錯誤日志,及時與我們聯系
AppStoreException
550 業務錯誤(BPMN Error)

當BPMN引擎執行時由開發者拋出BPMNError業務異常時,會返回該錯誤信息。遇到這種錯誤,請與業務開發者聯系
BPMNError
590 AWS Instance Server連接失敗

當客戶端以HTTP(S)經Web連接至AWS服務器時,未能正常建立通信連接時會返回該錯誤信息。遇到這種錯誤,可能是AWS服務已停止或Web與AWS之間的網絡故障
Web層錯誤
591 處理AWS Instance Server響應時發生錯誤

當客戶端以HTTP(S)與AWS服務器建立連接后,在發生指令請求等待返回結果發生錯誤時,會返回該錯誤信息。遇到這種錯誤,請檢查AWS的錯誤日志,及時與我們聯系
Web層錯誤
760 服務正在啟動(Instance Starting)

當服務器正在啟動尚未就緒時,會返回該錯誤信息。遇到這種錯誤,請稍后執行
*當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
761 服務正在關閉(Instance Stoping)

當服務器正在關閉時,會返回該錯誤信息。遇到這種錯誤,請不要再重復請求,服務器將被關閉
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
762 服務脫機(Instance Offline)

當服務器處於運行中,由運維人員暫停客戶端響應時,會返回該錯誤信息。遇到這種錯誤,請聯系系統管理員
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
770 應用正在啟動(App Starting)

當訪問的應用正在啟動尚未就緒時,會返回該錯誤信息。遇到這種錯誤,請稍后執行
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
771 應用正在關閉(App Stoping)

當訪問的應用正在關閉時,會返回該錯誤信息。遇到這種錯誤,請不要再重復請求,應用將被關閉
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
772 應用脫機(App Offline)

當應用處於就緒但依賴的應用未安裝或暫停后,會返回該錯誤信息,如果該應用未被授權或訂閱也會處於772狀態。遇到這種錯誤,排出錯誤后再啟動該應用
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
773 應用已卸載(App Uninstall)

當應用已經被卸載后,會返回該錯誤信息。遇到這種錯誤可以忽略,或訪問應用管理,將卸載的應用還原
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
774 應用出錯暫停(App Failed)

當應用啟動失敗后,會返回該錯誤信息。遇到這種錯誤,請檢查該應用的日志,排出錯誤后再啟動該應用
* 當客戶端請求AWS服務時,若處於該場景將以該錯誤碼返回到ResponseObject數據結構
800 許可配額限制(Quota Limit)

當資源配額超過許可限制時,會返回該錯誤信息。例如:超過許可的注冊用戶數
AWSQuotaException

* 當客戶端請求並超過許可證允許的最大並發返回到ResponseObject中

如何使用錯誤碼

  • 如果錯誤來自AWSException及其子類,可以通過getAPIErrorCode()在Java代碼中獲取
  • 如果錯誤來自客戶端API,可通過ResponseObject結構的errorCode讀取

 

 

3.2 異常拋出

  AWS平台提供的異常對象都是uncheck類型,開發者可以根據處理的需要進行捕獲,如果開發者非常明確的要拋出這些異常,那么可以不對其處理。

AWSAPIException外,所有AWS內部異常的父類都是AWSExceptione,常見異常如下:

Exception 說明
AWSAPIException API調用異常(uncheck)
AWSException AWS平台異常(以下均內部使用,uncheck)【通用】
AWSClassLoaderException 類加載異常
AWSEngineException 引擎內部異常(流程、表單、報表等,見該類常量)
BPMNDefException BPMN定義異常(設計階段)
BPMNError BPMN規范要求捕獲的異常拋出(運行階段)
AWSDataAccessException 數據操作異常。如數據庫操作、JSON數據操作
AWSIllegalArgumentException 參數校驗異常【通用】
AppStoreServiceException 訪問AWS企業應用商店異常

常用異常

雖然AWS平台定義了很多異常對象,但是對於應用開發者,只需要熟練掌握以下幾個,即可滿足大部分開發場景的需要:

  • AWSIllegalArgumentException(400)
  • AWSForbiddenException(403)
  • AWSObjectNotFindException(404)
  • AWSException(500)
//參數合法性異常 throw new AWSIllegalArgumentException("參數1", AWSIllegalArgumentException.FORMAT,"參數必須是0-9數字"); throw new AWSIllegalArgumentException("參數1", AWSIllegalArgumentException.EMPT); throw new AWSIllegalArgumentException("參數1不能為空"); //操作被拒絕 throw new AWSForbiddenException("流程已經掛起,操作被拒絕"); throw new AWSForbiddenException("ctx類型不當,應給定begin()返回的上下文對象"); //對象不存在 throw new AWSObjectNotFindException("App文件不存在[" + appFile.getPath() + "]"); throw new AWSObjectNotFindException("流程定義未找到。processDefinitionId:" + processDefinitionId); 

注意事項

  • 4類異常,通常可以直接拋出給前端處理
  • 5類異常,除非開發者捕獲該異常也無法提供解決方案,否則應在上層邏輯捕獲並處理
  • 7和8類異常屬於底層非預期信息,開發者不必捕獲可直接拋出
  • 在捕獲異常時,不建議直接捕獲Exception,除非你的意圖是處理掉所有異常的拋出
  • 如果開發者的程序捕獲了所有異常,應當使用e.printStackTrace(System.err)記錄日志

3.3 異常處理

當異常被AWS MVC頂層框架捕獲后,會根據cmd請求類型處理成客戶端能夠理解的文檔格式。

請求類型 格式
./w HTML Document
./jd JSON Document
./xd XML Document

Java Exception處理

當發生底層Java異常或其他非AWSException異常時,AWS MVC將該異常封裝成500錯誤。

異常日志

捕獲的異常被記錄至AWS logs目錄下

  • error.log(單一部署)
  • error-%AWS節點名%.log(集群部署)

HTML Document警告頁面

html異常頁面

JSON Document數據結構

JSON數據結構

XML Document數據結構

XML數據結構

 

4 國際化

4.1 多語言

AWS MVC框架對HTML/JavaScript多語言和Java程序多語言提供了一整套完善的開發方案,以下為AWS MVC的多語言處理架構。

多語言框架

AWS MVC每次接收到用戶請求時,在會話對象(UserContext.getLanguage())提供了該用戶的界面語言信息,AWS MVC為應用提供了兩種常見解決方案:

Java程序

通過SDK.getAppAPI().i18nValue()獲得指定用戶界面的多語言資源配置

SDK.getAppAPI().i18NValue("com.actionsoft.apps.poc.api", me, "info1") 

HTML模版

在HTML頁面或JavaScript中出現的多語言標簽,使用<I18N#變量名>替代,其中變量名為多語言資源配置ItemKey

<!doctype html> <html> <head> <meta charset="UTF-8"> <title><I18n#PageTitle></title> <script> var var1 = "<I18n#Var1>"; var var2 = "<I18N#Var2>"; alert(var1); alert(var2); </script> </head> <body> Hi,<I18n#PageTitle> </body> </html> 

多語言資源文件

遵循AWS PaaS對App的資源定義規范,每個AWS應用的多語言資源配置文件被存放在應用安裝目錄/i18n/下。

該目錄允許存在1個或多個符合Schema規范的xml文件,建議為自己的應用創建一個名為resource.xml的資源配置文件。

說明
item/key 多語言資源名,同個App下不允許重復
item/cn 中文簡體
item/en 英文
item/big5 中文繁體
item/%lang% 其他擴展的語言名

resource.xml示例

<locale-config> <lang> <item key="info1"> <cn><![CDATA[這是中文簡體語言]]></cn> <en><![CDATA[This is the English language]]></en> <big5><![CDATA[這是中文繁體語言]]></big5> </item> <item key="PageTitle"> <cn><![CDATA[這是標題]]></cn> <en><![CDATA[This is Title]]></en> <big5><![CDATA[這是標題]]></big5> </item> <item key="Var1"> <cn><![CDATA[這是變量1]]></cn> <en><![CDATA[This is Var1]]></en> <big5><![CDATA[這是變量1]]></big5> </item> <item key="Var2"> <cn><![CDATA[這是變量2]]></cn> <en><![CDATA[This is Var2]]></en> <big5><![CDATA[這是變量2]]></big5> </item> </lang> </locale-config> 

多語言資源文件管理

建議訪問AWS企業應用商店,安裝“多語言管理工具”。

該工具提供了可視化的多語言配置工具,能夠極大提高翻譯人員的工作效率。

如何擴展更多種語言

默認AWS PaaS只提供了中文簡體、英文和中文繁體三種界面語言,可以安裝“多語言管理工具”擴展更多種語言。

以下代碼打印出當前AWS PaaS支持的語言集

List<LanguageModel> langs = SDK.getPlatformAPI().getlanguages();
for (LanguageModel lang : langs) { System.out.println(lang.getName()); } 

4.2 時區和工作日歷

對於跨國企業/組織或長期國際差旅時,用戶需要根據工作地點的時區獲得與當地時間一致的日期信息,並遵守當地的節假日和企業工作時間要求。

在AWS MVC框架中,時區主要解決符合用戶當地時間的日期顯示;工作日歷主要解決對員工有效工作時間的計算,如流程執行效率,並提供API來處理業務需求,如差旅請假時長計算。

AWS是如何處理時區的

時區和工作日歷的管理和設置

工作日歷API接口

 

5 附錄1-編程資源

AWS MVC是一個開放的編程架構,你可以方便的將自己需要的工具包加入到自己的App中使用:

  • 三方Jar類庫 存放到App安裝目錄的lib下
  • 三方JavaScript、CSS庫 存放到Web層的apps/%appId%/

AWS PaaS提供的開源Jar類庫

可在你的程序中直接使用AWS PaaS自帶的一些第三方開源類庫,這些Jar文件存放在AWS安裝目錄的bin/libbin/jdbc下。

類庫 說明
commons-* Apache提供的若干工具類
barcode4j 條形碼生成
cajo RMI工具類
csv CSV數據處理工具
xalan/... XML數據處理
json-lib JSON數據處理
poi Office文件處理
httpclient HTTP客戶端
itext PDF處理
sigar 系統性能監控
log4j Java日志處理系統
cxf Web服務處理框架
... ...

AWS PaaS封裝的Web UI

這些組件全部基於JQuery和JQueryMobile底層框架封裝,使用這些UI有助於開發的應用界面與AWS其他應用保持一致的交互習慣。詳細說明參見AWS UI章節

5.1 SDK API

AWS PaaS作為App運行的容器環境和資源平台,為App開發者提供了豐富的API,這些API可以直接在你的Java程序中使用。

SDK結構

對於API詳細說明及用法,參見aws-api-doc(一個Java API Doc)。

MVC編程常用API

說明
SDK SDK API的總入口
ActionWeb Web(View)請求處理的父類
ModelBean 業務實體對象父類
DaoObject DAO對象父類
ResponseObject 返回JSON、XML結構化數據,如操作狀態、業務數據
UserContext 用戶會話,獲得用戶會話串、登錄IP、語言、設備類型、用戶組織等
AppAPI 多語言處理、跨應用的ASLP調用、應用日志
ORGAPI 訪問組織結構相關接口
PermAPI 訪問AWS權限相關接口
PortalAPI 訪問或構建門戶應用相關接口
RuleAPI 規則處理接口
DCAPI 文件處理接口

平台系統常用API

說明
PlatformAPI 查詢平台及服務狀態接口
ConfAPI 查詢平台常用配置參數接口
SLAAPI 監控告警接口

BPM引擎常用API

說明
ProcessAPI 流程實例控制接口
TaskAPI 任務實例控制接口
ProcessExecuteQuery 引擎執行結果查詢接口
ProcessQueryAPI 流程實例查詢接口
TaskQueryAPI 任務查詢接口
HistoryTaskQueryAPI 歷史任務查詢接口
DelegationAPI 任務委托/代理接口
RepositoryAPI 模型資源庫訪問接口
BOAPI BO操作接口
BOQueryAPI BO查詢接口

監聽器常見接口(事件編程)

說明
ValueListener 取值類監聽器父類
ExecuteListener 執行類監聽器父類
InterruptListener 中斷類監聽器父類

注意事項

  • 不推薦直接調用aws-api-doc未提供的接口方法
  • SDK API適用於在AWS Server端執行,不能用於Web層開發。如果你在Web層使用了不符合AWS MVC框架的開發模式,可以通過AWS CC發布Server API或封裝ASLP服務來訪問AWS Server端操作

 

5.2 AWS UI

為統一PaaS用戶的交互體驗(UX)和界面展示(UI),AWS MVC框架為開發者提供了一套基於JQuery封裝的JavaScript UI組件庫。目前這個UI庫仍處在完善中,如果增強了用戶體驗或封裝了新的UI類型,歡迎你的貢獻!請郵件聯系liujx@actionsoft.com.cn

了解每個AWS UI組件的文檔、示例,可本地啟動AWS服務后,在瀏覽器輸入以下url訪問。

http://localhost:8088/portal/commons/js/jquery/demo/index.html

在你的頁面引入AWS UI

以下代碼可將JQuery、AWS基本UI加入到你的頁面中。對於部分專用UI,請參見相關示例引入特定的資源

<link rel="stylesheet" type="text/css" href="../commons/css/awsui.css"> <script type="text/javascript" src="../commons/js/jquery/scripts/jquery.js"></script> <script type="text/javascript" src="../commons/js/awsui.js"></script> 

 

5.3 量命名詞匯表

為規范App開發者對專業變量的命名和識別,在這里給出一個詞匯表參考。

設計期

命名參考
存儲模型ID boDefId
表單模型ID formDefId
表單子表模型ID formItemDefId
流程模型ID processDefId
節點模型ID 通用:activityDefId
特定:userTaskDefId、serviceTaskDefId..
報表模型ID reportDefId
DW模型ID dwDefId
各種Context對象 如UserContext、TaskBehaviorContext...

建議:單獨出現時命名變量為ctx或context,同時出現多個不同類型的Context時,使用userContext、taskContext區分
登錄賬戶名 uid、uids(多個),對應ORGUSER的USERID字段
單位ID companyId
部門ID departmentId
角色ID roleId
小組ID teamId
小組成員ID teamMemberId

運行期

 

命名參考
流程實例ID 建議processInstId,可以使用processInstanceId
流程實例對象 建議processInst,可以使用processInstance
任務實例ID 建議taskInstId,可以使用taskId、taskInstanceId
任務實例對象 通用:建議taskInst,可以使用task、taskInstance
特定:建議historyTaskInst,可以使用historyTask、historyTaskInstance
BO表ID boId
BO表與流程實例綁定 通用:bindId
特定:純流程驅動場景下,也可使用processInstId

 

6 附錄2-程序文件

應用的安裝、部署和運行由AWS PaaS自動化完成,但在開發階段需要開發者了解這些資源結構。

Web層資源

Web層是指部署在Web Server(如Tomcat)的資源。AWS PaaS為每個App分配了獨立的目錄,被稱為Web層根資源根目錄。

你可以在這個目錄中規划自己的js、css等資源結構。

//存放Web參數解析配置 %AWS-HOME%/webserver/webapps/portal/apps/%appId%/action.xml //存放css %AWS-HOME%/webserver/webapps/portal/apps/%appId%/css/ //存放js %AWS-HOME%/webserver/webapps/portal/apps/%appId%/js/ //存放圖片 %AWS-HOME%/webserver/webapps/portal/apps/%appId%/img/ //存放jsp程序(*不允許jsp直連數據庫的開發模式,使用MVC cmd開發) %AWS-HOME%/webserver/webapps/portal/apps/%appId%/jsp/ //自定義 %AWS-HOME%/webserver/webapps/portal/apps/%appId%/.../ 
  • %AWS-HOME%是AWS PaaS的安裝根目錄
  • %appId%是應用的Id名

App層資源

App層是指部署在AWS Server的資源。AWS PaaS為每個App分配了獨立的目錄,並通過安裝、卸載庫進行管理。

在開發的應用在容器倉庫里處於install狀態,與MVC編程相關的目錄資源如下

//存放App的配置描述 %AWS-HOME%/apps/install/%appId%/manifest.xml //存放App的LOGO %AWS-HOME%/apps/install/%appId%/icon16.png %AWS-HOME%/apps/install/%appId%/icon64.png %AWS-HOME%/apps/install/%appId%/icon96.png //存放程序編譯的jar文件和第三方類庫 %AWS-HOME%/apps/install/%appId%/lib/ //存放HTML模版 %AWS-HOME%/apps/install/%appId%/template/page/ //存放多語言資源 %AWS-HOME%/apps/install/%appId%/i18n/resource.xml

7 附錄3-開發工具

AWS MVC的開發者可以根據自己的編程習慣選擇開發工具。

AWS Developer

當安裝了AWS PaaS開發環境后,會為開發者提供一個專有的開發工具。該工具基於Eclipse IDE封裝,提供了專有的擴展插件,能夠更直觀、高效的進行AWS App開發。

//開發工具根目錄 %AWS-HOME%/developer/ 

使用AWS Developer的優點

  • 無需配置即可在工程代碼中啟動、調試、編譯和分發操作
  • 根據Controller類自動生成Web端接參配置文件,提高工作效率
  • 向導式開發
    • 創建App應用
    • 創建cmd請求
    • 創建ModelBean
    • 創建Dao
    • 創建Cache
    • 管理系統Jar包依賴
    • 創建各種AWS擴展插件...
  • 提供對App各類參數的配置管理
  • 內嵌支持SVN代碼版本管理

Eclipse

對於熟悉AWS PaaS和App應用資源配置結構的開發者,也可以直接使用Eclipse完成所有的任務目標。

  1. 新建Java普通工程
  2. Java Build Path>Libraries下創建aws_lib庫,增加以下資源
    %AWS-HOME%/bin/lib/*.jar(含子目錄)
    %AWS-HOME%/bin/jdbc/*.jar
    
  3. 啟動aws-infrastructure-common.jarStartUp
    com.actionsoft.bpms.server.AWSServer.StartUp
    
  4. 指定啟動選項中Working directory目錄
    %AWS-HOME%/bin
    

developer.csr

在你的團隊正式開發應用前,應獲得應用開發者證書(ISV)。證書文件路徑如下

%AWS-HOME%/apps/developer.csr


8 微信企業號框架

微信企業號框架基於AWS MVC框架,將請求根據請求類型(URL跳轉、消息/事件)交由不同的Servlet處理,再根據請求的映射規則分發給相應的后端邏輯控制器進行處理。

AWS MVC編程架構

上圖中的三個Servlet(AWS Web Server / 一般請求Servlet,WS Web Server /重定向Servlet,WS Web Server /回調Servlet),后端處理控制(AWS App Server / Controller)和微信企業號管理平台是微信企業號的核心通信框架,AWS微信App是開發者實現業務邏輯的區域,主要元素描述如下:

說明
AWS Web Server 安裝有AWS Portal的標准Servlet容器,例如:Tomcat、WebLogic
AWS App Server 安裝有AWS Server的應用服務器,所有的業務邏輯在這里處理
一般請求Servlet 接收URL跳轉請求,收到請求后會檢查是否帶有包含用戶認證信息的Cookie,如果包含則封裝后轉發給后端控制器,若不包含則構造微信OAuth驗證鏈接,重定向到下面的重定向Servlet
重定向Servlet 處理微信OAuth驗證請求,封裝后轉發給后端控制器,最終交由微信管理平台處理並返回驗證結果。如果驗證通過,將驗證信息寫入Cookie,最后重定向到原始URL
回調Servlet 微信企業號應用的回調地址指向此處。處理微信消息/事件請求,封裝后轉發給后端控制器,再由微信管理平台轉發到指定的AWS微信App處理請求
后端處理控制器 通過注解攔截到方法,綁定邏輯處理程序
微信企業號管理平台 管理微信企業號應用,可為企業號應用設置、綁定菜單和指定處理消息/事件的AWS 微信App
AWS微信App 實現業務邏輯,一般包含H5頁面(View視圖組裝,Model/Dao/Cache模型,Template模板),和消息/事件處理實現類。

 

9 文檔歷史記錄

下表說明了對該文檔所做出的重要更改。

類型 說明 修改日期
首次發布 這是AWS MVC框架參考指南的首次發布 2015年01月22日


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM