基於Ofbiz的Web框架

1       Web開發概述

隨着互聯網的廣泛普及,越來越多的企業應用採用了B/S的交互模式。在開發基於B/S的企業應用中,如何把表示邏輯與業務邏輯分離開來,一直都是人們關注的一個焦點問題。

Web開發中引入MVC設計模式,是一個有效地解決辦法,目前看來是一個成功的辦法,也是人們仍然在做的事。MVC設計模式起源於Smalltalk語言,它由以下三個部分組成:模型(model),視圖(view),控制器(Controller)。

1.1    MVC設計模式

組件

描述

模型(model

封裝數據對象。模型用來封裝和顯示數據對象。

視圖(view

作爲模型的顯示,它表示數據對象的當前狀態。

控制器(Controller

定義對用戶的輸入執行相應操作的接口,它用來操作模型(model)和數據對象。

使用MVC的好處如下:

可靠性:表示層和業務層分離,這樣就允許你更改你的表示層代碼而不用重新編譯你的模型(model)和控制器(Controller)代碼。

高重用和適應性: MVC模式允許你使用各種不同樣式的視圖來訪問同一個服務器端的代碼。它包括任何WEBHTTP)瀏覽器或則無線瀏覽器(WAP)

快速的部署:開發時間會得到相當大的縮減,它使程序員(java開發人員)集中精力於業務邏輯,界面程序員(HTMLJSP開發人員)集中精力於表現形式上。

可維護性分離表示層和業務邏輯層也使得基於MVC實現Web應用更易於維護和修改。

1.2    StrutsMVC實現

Struts 的體系結構實現了Model-View-Controller設計模式的概念,它將這些概念映射到web應用程序的組件和概念中。

下面是處理步驟的描述 

1 由顯示視圖產生一個請求。

2  請求被ActionServlet(控制器)接收,它在struts-config.xml文件中尋找請求的URI,找到對應的Action類後,Action類執行相應的業務邏輯。

3  Action類執行建立在模型組件基礎上的業務邏輯,模型組件是和應用程序關聯的。

4  一旦Action類處理完業務邏輯,它把控制權返回給ActionServlet。,Action類提供一個鍵值作爲返回的一部分,它指明瞭處理的結果。ActionServlet使用這個鍵值來決定在什麼視圖中顯示Action的類處理結果。

5  ActionServletAction類的處理結果傳送到指定的視圖中,請求的過程也就完成了。

l         模型(The Model

Struts框架沒有提供特定的模型組件。

l         視圖(The View

Struts框架中視圖組件對應於一個簡單的JSP文件,這個JSP文件包含了Struts定義的標籤 。這些標籤在Struts框架中定義,它使struts應用項目和控制器之間實現鬆耦合。 

l         控制器(The Controller

控制器是Struts框架中的中樞,它由org.apache.struts.action.ActionServlet這個servlet來貫徹和執行的。這個org.apache.struts.action.ActionServlet接收所有客戶端的請求,並把請求委派到指定的Action(用戶擴展自org.apache.struts.action)ActionServlet委派請求是基於客戶端傳入的URI 一旦Action類完成處理,ActionServlet根據Action返回的鍵值來決定在什麼視圖中顯示Action的類處理結果。

1.3    Struts的優勢

由於Struts出現的歷史比較早,目前,Struts是最流行的Web開發框架,得到了最多開發人員和供應商的支持,是MVC應用的主流。

他的優勢很多,如開源、用戶羣衆多、文檔豐富、支持好、穩定、輕量級等等,在此不再詳述,因爲缺少合適的比較對象。

1.4    Struts的不足

然而,需要指出的是,Struts並不是唯一實現MVC模式的Web框架。儘管你可能已經習慣了Struts,感覺它很好、足夠用,但是,仔細想一想,再看一看別的Web框架,也許不難找出Struts的一些不足之處,這裏主要從宏觀的角度談談。

1.         沒有提供特定的模型組件。這是最明顯的缺點,模型要自己去實現、封裝,用最基本的java Bean可以想象當應用規模比較大時,設計和編碼的工作量有多大。當然,從某種意義上也可以說是個優點,因爲你可以自由選用自己的模型實現如EJB和其他OR Mapping

2.         Struts只是一個技術框架,也可以說僅僅是一個工具,因爲它沒有包含任何業務內容。是的,Struts不是一個業務框架,即使是一個登陸驗證這樣的基本服務你也需要從零開始編碼。

3.         難以勝任複雜的大規模級企業應用。實際上,在企業級應用中,Web層只是很薄的一層,並不是分出簡單的MVC就可以了。一個單純的技術框架是沒有多少實用價值的。用Struts做簡單的Web應用可以,對於複雜規模級應用,太多的東西要編碼,Struts顯得過於單薄。

2       Ofbiz的業務框架


2.1    Ofbiz概貌基於Ofbiz的Web框架 - tarcy_tw - 一粒塵埃

 

2.1.1    什麼是Ofbiz

OfbizOpen for business)是一個開源的,基於J2EEXML規範的,用於構建大型企業級、跨平臺、跨數據庫、跨應用服務器的多層、分佈式電子商務類WEB應用系統的框架(Framework)。

Ofbiz幾乎實現了所有的J2EE核心設計模式,各個模塊之間的耦合比較鬆散,用戶能夠比較容易的根據自己的需要進行拆卸。

Ofbiz內置了許多其它開源項目,如JBossPostgreSQLMySQLApacheJettyJOTMJpublishBeanShellAntBSFLog4J,等,提供了相對成本比較低的解決方案。同時,用戶也可以比容易的更換成其他組件,如將Jboss&&Tomcat換成Bea Weblogic或者IBM Websphere

2.1.2    Ofbiz  vs.  Struts

嚴格說來,OfbizStruts沒有可比性。Ofbiz做了很多人想做卻一直沒有做好的事,那就是把市面上的知名的開源項目整合起來,形成一個更有價值的業務框架。

Ofbiz包括了幾乎所有的軟件界的主流技術,所有能被利用的開源項目都被納入其中。但是,令人吃驚的是,Ofbiz卻沒有把廣爲應用的Struts包括進去,相反的採用了JPublish + FreeMaker + BeanShell這三個開源的東西來代替Struts。而要把Struts加進去取代這三者似乎不是一件容易的事。

Ofbiz的總設計師David E. Jones,沒有對Struts發表太多的見解,對此有一個簡單的解釋是:StrutsOfbiz的設計差別太大,沒有辦法無逢集成。以其能力寫一個MVC框架不是問題。

如果真要比較的話,那就是技術框架與業務框架的區別。Ofbiz提供了一整套的開發基於Javaweb應用程序的組件和工具;而Struts並沒有提供訪問數據庫的組件,也沒有提供控制工作流的組件。實際上,Struts是一個框架工具,Ofbiz遠不止於此,它還包含了部分業務功能及其基礎設施。

2.1.3    Ofbiz的好處

l         縮短開發週期,降低成本

據稱,很多基於J2EE的失敗實踐,都可以歸結於拙劣的設計。J2EE規範並不複雜,但是如何遵照J2EE規範,根據自己的業務需求,做一個合適的、高效的、可擴展的設計,是需要實際經驗和智慧的。國外的大中型系統基於J2EE的早就很多了,國內近幾年也多了起來,但是優秀的設計人員不是很多。

Ofbiz的價值在於它的架構非常好,不僅用到了幾乎所有的J2EE核心設計模式(Sun公司推薦的),而且還實現了工作流、業務規則引擎,以處理靈活的與變更。這樣,就避免了缺少優秀設計人員所造成的拙劣設計。

基於Ofbiz開發,無疑會縮短開發週期,好的設計以及工作流和業務規則引擎的引入,也最大程度的降低了系統的維護成本。

l         用很少的 Code 完成複雜的處理

這是Ofbiz 宣稱的優點之一。如果把Ofbiz消化了,則基於Ofbiz開發一個CRMERP系統會大大縮短開發週期,由於Ofbiz優良的設計,維護的成本應該比較小。

Ofbiz 已經完成了大部分業務類軟件系統都需要的部件,像用戶認證、工作流、業務規則處理等,很多業務需求都可以通過寫XML配置文件,以及很少的java代碼來完成。代碼量不大,但知道怎麼寫會比較費時。弄懂Ofbiz以後,寫實現代碼通常會比較簡單,只需要按照它的開發機制度就是了。

l         擴展性和移植性好

OFBIZ所提供的系統框架,是一個純Java的應用程序。框架提供的接口十分的完備,例如核心部件實體引擎,早期版本就有,已經十分的成熟。通過實體引擎,用戶不用直接操縱數據庫,建立庫表、查詢、視圖、觸發器等都可以通過寫XML配置文件來完成。也有人提出,實體引擎不能夠處理複雜的SQL查詢,實際上,一方面這種複雜的SQL查詢很少遇到,另一方面實體引擎也同樣允許你用SQL代碼來操縱這種複雜的查詢。

OFBIZ開發者同時維護和WeblogicTomcatJbossResinOrion16個廠商的WebApp應用服務器的兼容版本.

OFBIZ開發者同時維護和OracleMySqlSybasePostgreSQLHsql等數據庫產品的兼容支持,包括編譯、打包、部署到這些數據庫產品或應用服務器產品的運行環境下。

OFBIZ開發者同時在UnixWindows兩大操作系統上進行開發和測試,而且具備Java應用系統的所有跨平臺的特點。

有了這些,對於大型企業級應用系統的具體、特定實現來說,你有信心實現所謂的“一次開發,到處運行”。

l         沒有版權問題

免費的,可以用於商業目的,可以分發。

2.2    OfbizMVC 模式實現

Ofbiz最大的價值,也許就是它不僅僅是一個技術框架,更是一個實現企業應用得很好的業務框架。它的MVC模式不僅僅是Web層,而是貫穿於業務層和數據層,每一層都有出色的控制器。

2.2.1    數據層的控制器 (Entity Engine)

實體引擎是Ofbiz最有價值、最核心的、也是最穩定的一個數據層控制器,通過它基本不用編碼或很少編碼就可以訪問數據層。Ofbiz提供了用XML些配置文件的方法來操縱數據。

實體引擎的功能類似於CICS、實體EJB、以及其他O-R Mapper。但是,Ofbiz的實體引擎不僅強大、而且靈活,程序員不需要JDBC知識,不用寫SQL代碼。基本上,實體引擎的封裝能夠解決絕大部分的數據庫操作,同時,也提供了給你寫SQL代碼,實現複雜SQL查詢的空間。

實體引擎採用了不少核心J2EE設計模式,如值對象、代表、助手等模式,用戶的API接口比較友好。

2.2.2    邏輯層的控制器 (Service Engine)

服務引擎是Ofbiz的另一個核心組件。Ofbiz只有這兩個核心組件。實體引擎代表業務數據,而服務引擎代表了業務邏輯。

引入服務引擎的另一個價值是,它使得Ofbiz業務框架不限於Web應用。非Web的客戶端包括java 應用、EJB、甚至SOAP都可以直接調用,這樣,框架的可擴展性非常好。

服務引擎的服務可以分爲同步、異步(關心還是忽略結果),支持JMS。具體實現方式可以是一個java 靜態方法、工作流、Bean Shell腳本等。

2.2.3    Web層控制器 (Control Servlet, JPublish, etc)

Web層控制器的核心是Control Servlet。和Struts一樣,Web層的流控制器的配置文件也是一個XML文件         

根元素是一個<site-conf>,對應一個Website。如下的例子是一個Website的部分配置。類型爲requesthandler是控制器配置,指明瞭應該如何處理request,可以看到有javabshsoapsimple等,這些都是服務引擎的類型,如simple是簡單的java靜態方法,soapweb服務。類型爲requesthandlerView的配置,與Struts不同,View不僅僅只有Jsp,還有velocityjpublish等。另外,還有region這種視圖,region是網頁中的某一塊區域。

Ofbiz支持https,只需要指明某個請求的服務類型就行。登陸認證基本上實現的比較好,只要在配置文件中指明即可。

<site-conf>

    <description>OFBiz: eCommerce Controller Configuration File</description>

    <owner>The Open For Business Project Copyright (c) 2001-2003</owner>

    <errorpage>/error/error.jsp</errorpage>

    <handler name="java" type="request" class="org.ofbiz.content.webapp.event.JavaEventHandler"/>

    <handler name="bsf" type="request" class="org.ofbiz.content.webapp.event.BsfEventHandler"/>

    <handler name="soap" type="request" class="org.ofbiz.content.webapp.event.SOAPEventHandler"/>

    <handler name="service" type="request" class="org.ofbiz.content.webapp.event.ServiceEventHandler"/>

    <handler name="service-multi" type="request" class="org.ofbiz.content.webapp.event.ServiceMultiEventHandler"/>

    <handler name="simple" type="request" class="org.ofbiz.content.webapp.event.SimpleEventHandler"/>

 

    <handler name="jsp" type="view" class="org.ofbiz.content.webapp.view.JspViewHandler"/>

    <handler name="region" type="view" class="org.ofbiz.content.webapp.view.RegionViewHandler"/>

    <handler name="ftl" type="view" class="org.ofbiz.content.webapp.ftl.FreeMarkerViewHandler"/>

    <handler name="velocity" type="view" class="org.ofbiz.content.webapp.view.VelocityViewHandler"/>

    <handler name="http" type="view" class="org.ofbiz.content.webapp.view.HttpViewHandler"/>

    <handler name="jpublish" type="view" class="org.ofbiz.content.webapp.view.JPublishViewHandler"/>

 

    <!-- Events run from here for the first hit in a visit -->

    <firstvisit>

        <event type="java" path="org.ofbiz.securityext.login.LoginEvents" invoke="autoLoginCheck"/>

        <event type="java" path="org.ofbiz.marketing.tracking.TrackingCodeEvents" invoke="checkTrackingCodeCookies"/>

        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="setDefaultStoreSettings"/>

    </firstvisit>

 

    <!-- Events to run on every request before security (chains exempt) -->

    <preprocessor>

        <!-- This event allows affilate/distributor entry on any page -->

        <event type="java" path="org.ofbiz.securityext.login.LoginEvents" invoke="checkExternalLoginKey"/>

        <event type="java" path="org.ofbiz.ecommerce.misc.ThirdPartyEvents" invoke="setAssociationId"/>

        <event type="java" path="org.ofbiz.marketing.tracking.TrackingCodeEvents" invoke="checkTrackingCodeUrlParam"/>

        <event type="java" path="org.ofbiz.marketing.tracking.TrackingCodeEvents" invoke="checkPartnerTrackingCodeUrlParam"/>

    </preprocessor>

 

    <!-- Events to run on every request after all other processing (chains exempt) -->

    <!--

    <postprocessor>

        <event type="java" path="org.ofbiz.content.webapp.event.TestEvent" invoke="test"/>

    </postprocessor>

    -->

 

    <!-- Security Mappings -->

    <request-map uri="checkLogin" edit="false">

        <description>Verify a user is logged in.</description>

        <security https="true" auth="false"/>

        <event type="java" path="org.ofbiz.securityext.login.LoginEvents" invoke="checkLogin" />

        <response name="success" type="view" value="main" />

        <response name="error" type="view" value="login" />

    </request-map>

 

    <request-map uri="login">

        <security https="true" auth="false"/>

        <event type="java" path="org.ofbiz.securityext.login.LoginEvents" invoke="login"/>

        <response name="success" type="request" value="updatedistributor"/>

        <response name="error" type="view" value="login"/>

    </request-map>

    <request-map uri="view">

        <response name="success" type="view" value="main"/>

        <response name="error" type="view" value="error"/>

    </request-map>

。。。

2.3    Web請求執行流程

從請求到響應,流程如下:

l         Browser發起請求;

l         Control Servlet被調用;

l         在配置文件中查詢請求該如何處理;

l         安全檢查 (加密和認證)

l         調用事件(如果定義了事件):

查找爲這個事件定義了哪些服務?

例如,找到了一個simple method類型的服務,則調用這個服務,

具體實現這個的服務引擎(簡單的java靜態方法)調用實體引擎或者不用實體引擎,完成業務計算、數據庫訪問。

l         響應執行的結果;

執行的結果與請求一樣都是封裝成map類中,結果如何展示呢?

就是View了。

首先查詢定義了哪些View,找到了定義,是一個Region或者Jpublish page,則

調用模板(template,參見JPublish),然後是Sections被填充,顯示數據。

模板中有一些腳本變量被來自於實體引擎或者服務的數據代替,

這樣,最終的界面就出來的。

發佈了9 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章