Java開源架構Jdon應用系統案例開發
案例場景:每個系統都是從域建模入手設計,通過建模將業務需求轉化為軟件域范圍的模型,本文以圍繞一個模型實現該模型的基本功能:增刪改查(CRUD)和批量分頁查詢,通過Jdon框架的迅速簡化高質量的開發,建立一個復雜系統的基礎部分,使得開發者將真正精力集中在每個項目系統的特殊業務處理。
源碼見Jdon框架源碼包中的Jdonsample項目。
案例需求:簡單的留言簿,實現留言Message模型的新增、修改、刪除和批量查詢。
增刪改查(CRUD)和批量分頁查詢是每個系統的基本功能,下面分這兩部分描述。
CRUD開發步驟
說明:每個應用系統中存在大量重復的CRUD開發流程,通過本框架可快速完成這些基本基礎工作量,將精力集中在特殊功能設計上。
CRUD快速開發主要簡化了表現層的流程,將其固化,或者是模板化,以配置替代代碼編制,靈活而快速。每個Model一套固化CRUD流程。
開發步驟分兩個小部分:代碼編寫和配置。
代碼:三步代碼編寫
代碼只需要三步:
第一步:域建模:建立sample.model.Message,如下:
注意點:
·模型類Message必須繼承框架的com.jdon.controller.model.Model,或者實現com.jdon.controller.model.ModelIF接口。
·該模型類必須有一個能夠標識其對象唯一性的主鍵,如messageId,這個主鍵相當于數據表的主鍵。
第二步:建立Model組件服務:首先建立模型Message的服務接口sample.service. MessageService:
至于MessageService的具體實現子類可以在現在或者以后建立,可見源碼包中的sample.service.MessageServiceImp。
第三步:建立Model的表現層邊界模型:sample.web.MessageForm,必須繼承框架的ModelForm,如下:
表現層MessageForm內容基本上是從業務層模型Message類中拷貝過來的,主要是為了保持MessageForm和Message的字段一致,我們就可以通過框架內MessageForm和Message的相同字段的復制進行數據傳送,將業務層的Message數據傳送到表現層MessageForm;或將界面表現層MessageForm傳送到Message中。
一個模型Message有關CRUD實現的代碼工作到此結束,如果有其他模型,完全按照上述三個步驟再做一次,是不是不太費腦筋?有點模板化開發味道?下面談談CRUD實現第二組成部分:配置。
配置分兩個配置文件,這兩個配置文件分別是:
·將前面三步編寫的類建立關系:jdonframework.xml
·配置界面流程:struts-config.xml
配置之一:Jdon框架配置文件
首先我們將前面三步編寫的三個類:模型Message、服務MessageService和界面模型MessageForm建立起聯系,也就是告訴Jdon框架這三者是解決一個模型增刪改查CRUD功能實現的。
由于這個配置文件是告訴Jdon框架的,因此,我們取名為jdonframework.xml,當然你也可以取其他名稱,無論取什么名稱,都要告訴Jdon框架,在struts-config.xml中配置
jdonframework.xml配置內容如下:
以上配置是配置模型Message、模型服務MessageService和界面模型MessageForm三者關系的,下面詳細說明三個部分的配置:
一、模型Message的配置:
這是通過第一行中的class值來指定當前Model是sample.model.Message:
其中,Message模型的主鍵是messageId,這個messageId必須是Message類的一個字段;同時是用來唯一標識唯一的Message模型對象,也就是Object ID,或者可以認為是模型Message對應的數據表message的主鍵。
二、界面模型MessageForm配置:
可能你已經注意到:這里并沒有寫界面模型完整類:sample.web.MessageForm,而好像是MessageForm類的名稱messageForm。
那么配置中messageForm名稱是從哪里來的呢?是struts-config.xml中ActionForm定義名稱,如下:
可見我們的界面模型完整類sample.web.MessageForm是在struts-config.xml中form-beans中配置,并且命名為messageForm,而這個messageForm就是jdonframework.xml中的messageForm。
三、模型服務MessageService配置:
在jdonframework.xml中首先申明MessageService完整實現是類sample.service.MessageServiceImp,并且取名為messageService:
<pojoService name="messageService" class="sample.service.MessageServiceImp"/>
這樣,我們就可以詳細將我們自己編寫的messageService的CRUD方法名告訴Jdon框架了:
黑體字部分正是messageService所指的類sample.service.MessageServiceImp所繼承的接口sample.service. MessageService四個方法,可見前面代碼步驟第二步。
配置之二:界面流程配置
界面流程主要是配置CRUD界面流程,Jdon框架CRUD流程主要分兩個部分:第一是推出供用戶新增修改刪除的頁面;第二是接受用戶提交新增修改過的數據,以便遞交到業務層保存。
這部分配置主要是配置struts-config.xml:
第一、配置推出CRUD頁面流程:
其中com.jdon.strutsutil.ModelViewAction是Jdon框架類。只要客戶端瀏覽器調用http://localhost:8080/messageAction.do,通過上述配置將激活forward的name="create"流程,就能得到一個空白表單的頁面message.jsp;如果客戶端瀏覽器調用http://localhost:8080/messageAction.do?action=edit&messageId=18,通過上述配置將激活forward name="edit"流程,得到一個填滿數據的表單頁面,供用戶修改。
第二、配置:接受用戶提交新增修改過的數據,以便遞交到業務層保存:
其實在上一步的message.jsp中已經使用到這一步的配置,在message.jsp的表單action值就是本步配置的path值:/messageSaveAction.do:
在上面message.jsp中一定要有<html:hidden property="action"/>一行。
至此,模型Message的CRUD功能開發完畢。
批量查詢實現
代碼:三步代碼編寫
第一步、表現層編寫一個查詢Action,繼承Jdon框架的com.jdon.strutsutil.ModelListAction,該類名稱為sample.web. MessageListAction,完成getPageIterator和findModelByKey兩個方法。
其中getPageIterator方法內容是業務層MessageService的調用:
所以MessageService接口中必須有getAllMessages這個方法,主要功能是返回PageIterator對象
findModelByKey方法內容也是業務層MessageService的調用:
MessageService接口中必須有getMessage方法。
第二步、業務層實現MessageService接口方法getAllMessages內容,一般是直接調用持久層MessageDao方法。
第三步、持久層實現返回PageIterator對象:
如果有參數,可以如下查詢:
配置之一:Jdon框架配置文件
本步驟主要是需要告訴jdonframework.xml我們的MessageService實現子類是什么,以及調用的MessageDao等組件,jdonframework.xml如下:
因為MessageServiceImp類中調用了MessageDAO,MessageDAO中又涉及JNDI名稱,所以它們之間依賴關系靠Jdon框架的IOC容器實現。MessageServiceImp必須有構造器如下:
配置之二:界面流程配置
這一步主要是struts-config.xml配置,和通常struts的ActionForm和Action配置類似:
其中com.jdon.strutsutil.ModelListForm是框架批量查詢特別使用的類。
其中sample.web.MessageListAction是我們前面代碼編寫部分編寫的代碼。這樣,客戶端瀏覽器通過http://localhost:8080/ messageListAction.do就可以實現所有Message批量分頁查詢顯示。
注意,messageList.jsp中編碼和通常Struts的Jsp編碼是一樣的,需要使用logic:iterator從ActionForm為listForm的list字段中獲取單個的Message對象,然后顯示這些單個Message對象,,如下:
在messageList.jsp中加入下面標簽庫可以自動顯示多頁,缺省一個頁面顯示30個條目。
模型Message的批量查詢功能已經全部完成。
源碼見Jdon框架源碼包中的Jdonsample項目。
案例需求:簡單的留言簿,實現留言Message模型的新增、修改、刪除和批量查詢。
增刪改查(CRUD)和批量分頁查詢是每個系統的基本功能,下面分這兩部分描述。
CRUD開發步驟
說明:每個應用系統中存在大量重復的CRUD開發流程,通過本框架可快速完成這些基本基礎工作量,將精力集中在特殊功能設計上。
CRUD快速開發主要簡化了表現層的流程,將其固化,或者是模板化,以配置替代代碼編制,靈活而快速。每個Model一套固化CRUD流程。
開發步驟分兩個小部分:代碼編寫和配置。
代碼:三步代碼編寫
代碼只需要三步:
第一步:域建模:建立sample.model.Message,如下:
public class Message extends Model { private Long messageId; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } |
注意點:
·模型類Message必須繼承框架的com.jdon.controller.model.Model,或者實現com.jdon.controller.model.ModelIF接口。
·該模型類必須有一個能夠標識其對象唯一性的主鍵,如messageId,這個主鍵相當于數據表的主鍵。
第二步:建立Model組件服務:首先建立模型Message的服務接口sample.service. MessageService:
public interface MessageService { public void createMessage(EventModel em); public void updateMessage(EventModel em); public void deleteMessage(EventModel em); public Message getMessage(String messageId); } |
至于MessageService的具體實現子類可以在現在或者以后建立,可見源碼包中的sample.service.MessageServiceImp。
第三步:建立Model的表現層邊界模型:sample.web.MessageForm,必須繼承框架的ModelForm,如下:
public class MessageForm extends ModelForm { private String messageId; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } |
表現層MessageForm內容基本上是從業務層模型Message類中拷貝過來的,主要是為了保持MessageForm和Message的字段一致,我們就可以通過框架內MessageForm和Message的相同字段的復制進行數據傳送,將業務層的Message數據傳送到表現層MessageForm;或將界面表現層MessageForm傳送到Message中。
一個模型Message有關CRUD實現的代碼工作到此結束,如果有其他模型,完全按照上述三個步驟再做一次,是不是不太費腦筋?有點模板化開發味道?下面談談CRUD實現第二組成部分:配置。
配置分兩個配置文件,這兩個配置文件分別是:
·將前面三步編寫的類建立關系:jdonframework.xml
·配置界面流程:struts-config.xml
配置之一:Jdon框架配置文件
首先我們將前面三步編寫的三個類:模型Message、服務MessageService和界面模型MessageForm建立起聯系,也就是告訴Jdon框架這三者是解決一個模型增刪改查CRUD功能實現的。
由于這個配置文件是告訴Jdon框架的,因此,我們取名為jdonframework.xml,當然你也可以取其他名稱,無論取什么名稱,都要告訴Jdon框架,在struts-config.xml中配置
<plug-in className="com.jdon.strutsutil.InitPlugIn"> <set-property property="modelmapping-config" value="jdonframework.xml" /> </plug-in> |
jdonframework.xml配置內容如下:
<models> <!-- 配置模型的類是Message,其主鍵是messageId --> <model key="messageId" class ="sample.model.Message"> <!-- 下行是配置界面模型MessageForm --> <actionForm name="messageForm"/> <handler> <!-- 以下配置MessageService --> <service ref="messageService"> <getMethod name="getMessage" /> <createMethod name="createMessage" /> <updateMethod name="updateMessage" /> <deleteMethod name="deleteMessage" /> </service> </handler> </model> </models> <services> <!-- 以下配置MessageService --> <pojoService name="messageService" class="sample.service.MessageServiceImp"/> </services> |
以上配置是配置模型Message、模型服務MessageService和界面模型MessageForm三者關系的,下面詳細說明三個部分的配置:
一、模型Message的配置:
這是通過第一行中的class值來指定當前Model是sample.model.Message:
<model key="messageId" class ="sample.model.Message"> |
其中,Message模型的主鍵是messageId,這個messageId必須是Message類的一個字段;同時是用來唯一標識唯一的Message模型對象,也就是Object ID,或者可以認為是模型Message對應的數據表message的主鍵。
二、界面模型MessageForm配置:
<actionForm name="messageForm"/> |
可能你已經注意到:這里并沒有寫界面模型完整類:sample.web.MessageForm,而好像是MessageForm類的名稱messageForm。
那么配置中messageForm名稱是從哪里來的呢?是struts-config.xml中ActionForm定義名稱,如下:
<struts-config> <form-beans> <form-bean name="messageForm" type="sample.web.MessageForm" /> …… </form-beans> ….. </struts-config> |
可見我們的界面模型完整類sample.web.MessageForm是在struts-config.xml中form-beans中配置,并且命名為messageForm,而這個messageForm就是jdonframework.xml中的messageForm。
三、模型服務MessageService配置:
在jdonframework.xml中首先申明MessageService完整實現是類sample.service.MessageServiceImp,并且取名為messageService:
<pojoService name="messageService" class="sample.service.MessageServiceImp"/>
這樣,我們就可以詳細將我們自己編寫的messageService的CRUD方法名告訴Jdon框架了:
<handler> <!-- 以下配置MessageService --> <service ref="messageService"> <getMethod name="getMessage" /> <createMethod name="createMessage" /> <updateMethod name="updateMessage" /> <deleteMethod name="deleteMessage" /> </service> </handler> |
黑體字部分正是messageService所指的類sample.service.MessageServiceImp所繼承的接口sample.service. MessageService四個方法,可見前面代碼步驟第二步。
配置之二:界面流程配置
界面流程主要是配置CRUD界面流程,Jdon框架CRUD流程主要分兩個部分:第一是推出供用戶新增修改刪除的頁面;第二是接受用戶提交新增修改過的數據,以便遞交到業務層保存。
這部分配置主要是配置struts-config.xml:
第一、配置推出CRUD頁面流程:
<action name="messageForm" path="/messageAction" type="com.jdon.strutsutil.ModelViewAction" scope="request" validate="false"> <forward name="create" path="/message.jsp" /> <forward name="edit" path="/message.jsp" /> </action> |
其中com.jdon.strutsutil.ModelViewAction是Jdon框架類。只要客戶端瀏覽器調用http://localhost:8080/messageAction.do,通過上述配置將激活forward的name="create"流程,就能得到一個空白表單的頁面message.jsp;如果客戶端瀏覽器調用http://localhost:8080/messageAction.do?action=edit&messageId=18,通過上述配置將激活forward name="edit"流程,得到一個填滿數據的表單頁面,供用戶修改。
第二、配置:接受用戶提交新增修改過的數據,以便遞交到業務層保存:
<action name="messageForm" path="/messageSaveAction" type="com.jdon.strutsutil.ModelSaveAction" scope="request" validate="true" input="/message.jsp"> <forward name="success" path="/result.jsp" /> <forward name="failure" path="/result.jsp" /> </action> |
其實在上一步的message.jsp中已經使用到這一步的配置,在message.jsp的表單action值就是本步配置的path值:/messageSaveAction.do:
<html:form action="/messageSaveAction.do" method="POST" > <html:hidden property="action"/> MessageId:<html:text property="messageId"/> <br>Name:<html:text property="name"/> <br><html:submit property="submit" value="Submit"/> </html:form> |
在上面message.jsp中一定要有<html:hidden property="action"/>一行。
至此,模型Message的CRUD功能開發完畢。
批量查詢實現
代碼:三步代碼編寫
第一步、表現層編寫一個查詢Action,繼承Jdon框架的com.jdon.strutsutil.ModelListAction,該類名稱為sample.web. MessageListAction,完成getPageIterator和findModelByKey兩個方法。
其中getPageIterator方法內容是業務層MessageService的調用:
MessageService messageService= (MessageService) WebAppUtil.getService("messageService",request); return messageService.getAllMessages(start, count); |
所以MessageService接口中必須有getAllMessages這個方法,主要功能是返回PageIterator對象
findModelByKey方法內容也是業務層MessageService的調用:
MessageService messageService= (MessageService) WebAppUtil.getService("messageService", request); return messageService.getMessage((String)key); |
MessageService接口中必須有getMessage方法。
第二步、業務層實現MessageService接口方法getAllMessages內容,一般是直接調用持久層MessageDao方法。
第三步、持久層實現返回PageIterator對象:
public PageIterator getMessages(int start, int count) throws Exception { String GET_ALL_ITEMS_ALLCOUNT = "select count(1) from testmessage "; String GET_ALL_ITEMS = "select messageId from testmessage "; return pageIteratorSolverOfMessage. getPageIterator (GET_ALL_ITEMS_ALLCOUNT, GET_ALL_ITEMS, "",start, count); } |
如果有參數,可以如下查詢:
public PageIterator getMessages(Long categoryId, int start, int count) { String GET_ALL_ITEMS_ALLCOUNT = "select count(1) from message where categoryId = ? "; String GET_ALL_ITEMS = "select messageId from message where categoryId = ? "; Collection params = new ArrayList(1); params.add(categoryId);//參數放在Collection中 return pageIteratorSolver.getPageIterator(GET_ALL_ITEMS_ALLCOUNT, GET_ALL_ITEMS, params, start, count); } |
配置之一:Jdon框架配置文件
本步驟主要是需要告訴jdonframework.xml我們的MessageService實現子類是什么,以及調用的MessageDao等組件,jdonframework.xml如下:
<services> <pojoService name="messageService" class="sample.service.MessageServiceImp"/> <component name="messageDAO" class="sample.dao.MessageDAO"/> <component name="constants" class="sample.Constants"> <constructor value="java:/TestDS"/> </component> </services> |
因為MessageServiceImp類中調用了MessageDAO,MessageDAO中又涉及JNDI名稱,所以它們之間依賴關系靠Jdon框架的IOC容器實現。MessageServiceImp必須有構造器如下:
public class MessageServiceImp implements MessageService{ private MessageDAO messageDAO; public MessageServiceImp(MessageDAO messageDAO){ this.messageDAO = messageDAO; } } |
配置之二:界面流程配置
這一步主要是struts-config.xml配置,和通常struts的ActionForm和Action配置類似:
<form-beans> …… <form-bean name="listForm" type="com.jdon.strutsutil.ModelListForm" /> </form-beans> |
其中com.jdon.strutsutil.ModelListForm是框架批量查詢特別使用的類。
<action name="listForm" path="/messageListAction" type="sample.web.MessageListAction" scope="request"> <forward name="success" path="/messageList.jsp" /> </action> |
其中sample.web.MessageListAction是我們前面代碼編寫部分編寫的代碼。這樣,客戶端瀏覽器通過http://localhost:8080/ messageListAction.do就可以實現所有Message批量分頁查詢顯示。
注意,messageList.jsp中編碼和通常Struts的Jsp編碼是一樣的,需要使用logic:iterator從ActionForm為listForm的list字段中獲取單個的Message對象,然后顯示這些單個Message對象,,如下:
<logic:iterate indexId="i" id="message" name="listForm" property="list" > <bean:write name="message" property="name" /> ......... </logic:iterate |
在messageList.jsp中加入下面標簽庫可以自動顯示多頁,缺省一個頁面顯示30個條目。
<MultiPages:pager actionFormName="listForm" page="/messageListAction.do"> <MultiPages:prev name="[Prev ]" /> <MultiPages:index displayCount="1" /> <MultiPages:next name="[Next ]" /> </MultiPages:pager> |
模型Message的批量查詢功能已經全部完成。