由於新工作是在AWS PaaS平台上進行開發,為不耽誤工作,先整理一下AWS MVS的使用規范,快速上手。對AWS PaaS平台的相關介紹留到以后再來補充。本文幾乎是對官方學習文檔的整理,有遺漏的后補。
1.簡介
AWS MVC(Model-View-Controller),輕量級、高性能,是開發AWS App的標准框架,同時AWS PaaS自身也是基於它開發。與傳統開源的Spring MVC、Strusts2相比:
- 清晰、干凈、
請求驅動
(請求-響應)的輕量級Web編程框架 - 學習難度遠小於Spring MVC和Strusts2
No Servlet
、No JSP
,Just J2SE
,更容易的開發調試和問題追蹤- 與AWS平台架構兼容的會話安全、DAO、I18N國際化、日志、審計和SLA告警機制
- 沒有值棧、OGNL表達式、標簽庫等增加代碼復雜度和性能下降的架構缺陷
- 優於Strusts2的注解編程和方法攔截,能直接根據注解綁定Request參數,更簡潔
- 對處理結果是HTML、JSON、XML數據結構和錯誤碼的統一處理,避免業務架構缺陷
- 提供了一套基於JQuery和JQuery 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
進行檢查,只有當result
為ok
時從data
中讀取結果,否則應該檢查errorCode
及msg
項,並處理該異常(如提醒操作者或其他操作)。模擬一個停機故障:關閉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將接收到對應name
的cookie
值type=header
時,該參數的值來自請求內容的header,Controller將接收到對應name
的header
值
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必須由DCContext
的getDownloadURL()
獲取。
-
以下是獲取文件下載鏈接的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
默認ResponseObject
的toString()
將數據結構拼裝成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開發框架一樣,編寫出結構清晰的程序代碼,需要對業務實體對象進行屬性封裝(概念如POJO
、JavaBean
)。
AWS MVC提供了設計業務實體對象的父類ModelBean
和IModelBean
接口,采用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開發示例
- 繼承
ModelBean
,實現業務實體對象 -
繼承
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-doc的
DBSql
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警告頁面
JSON Document數據結構
XML Document數據結構
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#變量名
>替代,其中變量名為多語言資源配置Item
的Key
。
<!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/lib
和bin/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程序中使用。
對於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完成所有的任務目標。
- 新建
Java普通工程
- 在
Java Build Path>Libraries
下創建aws_lib
庫,增加以下資源%AWS-HOME%/bin/lib/*.jar(含子目錄) %AWS-HOME%/bin/jdbc/*.jar
- 啟動
aws-infrastructure-common.jar
的StartUp
com.actionsoft.bpms.server.AWSServer.StartUp
- 指定啟動選項中
Working directory
目錄%AWS-HOME%/bin
developer.csr
在你的團隊正式開發應用前,應獲得應用開發者證書(ISV)。證書文件路徑如下
%AWS-HOME%/apps/developer.csr
8 微信企業號框架
微信企業號框架基於AWS MVC框架,將請求根據請求類型(URL跳轉、消息/事件)交由不同的Servlet處理,再根據請求的映射規則分發給相應的后端邏輯控制器進行處理。
上圖中的三個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日 |