1. 程式人生 > >ApacheOFBiz的相關介紹以及使用總結(一)

ApacheOFBiz的相關介紹以及使用總結(一)

由於最近一段時間在給一個創業的公司做客戶關係管理CRM系統,限於人力要求(其實是沒有多少人力),只能看能否有穩定,開源的半成品進行改造,而且最好不需要前端(js)相關開發人員的支援就可以把事情做成,經過一段時間(其實也就是1周)的調研,最好把目標鎖定在OFBiz上。

OFBiz簡介,什麼是OFBiz

OFBiz is an Apache Software Foundation top level project. Apache  OFBiz全稱是The ApacheOpen For Business Project。是開放的電子商務平臺,是一個非常著名的開源專案,提供了建立基於最新的J2EE/XML規範和技術標準,構建大中型企業級、快平臺、跨資料庫、跨應用伺服器的多層、分散式電子商務類WEB應用系統的框架。 OFBiz幾乎實現了所有的J2EE核心設計模式,各個模組之間的耦合比較鬆散,使用者能夠比較容易的根據自己的需要進行拆卸,非常靈活。下面介紹一下它的目錄結構以及檔案說明。 可以參考一些blog中關於OFBiz的討論:

Apache OFBiz進行環境部署

Apache OFBiz是一個商業軟體架構,opentaps 基於 Apache OFBiz 的解決方案,其官方網站地址: 在官網中下載最新版本的OFBiz:apache-ofbiz-13.07.02.zip 將其解壓,執行命令
ant
ant load-demo
cd tools
./startofbiz.sh
  執行完成後,就可以在本機的下面url中的檢視相應的功能: 其中,管理員的使用者名稱 admin/ofbiz,登入後的介面如下(其中修改了預設的視覺風格): 

 

一些重要的配置檔案

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

component-load.xml 

路徑:ofbiz\application\,該配置檔案的作用為模組載入檔案,定義了所有在OFBIZ啟動時需要載入的應用程式的位置,當你建立了新的應用程式時,別忘了在該檔案中新增應用程式的位置資訊,在 ofbiz\hot-deploy\目錄下的應用程式不需要在component-load.xml裡定義,ofbiz啟動時會自動載入所有hot- deploy下的內容。

ofbiz-component.xml  

位置:基於ofbiz的任何應用程式根目錄下,指出該應用程式資料模型(<entity-resource>),商業邏輯(<service-resource>),web應用程式(<webapp.../>)的位置。 例子:  
<entity-resource type="model" reader-name="main"   loader="main" location="entitydef/entitymodel.xml" />   
<service-resource type="model" loader="main"   location="servicedef/services_agreement.xml" />
<webapp name="accounting" title="Accounting" server="default-server" location="webapp/accounting"  base-permission="OFBTOOLS,ACCOUNTING" mount-point="/accounting" />  
 

web.xml  

位置:應用程式\webapp\accounting\WEB-INF,用於配置main servlet(s),控制後臺伺服器(如tomcat server),及一些相關引數。 

controller.xml  

位置:應用程式\webapp\accounting\WEB-INF,作用:負責控制接收到的請求request。任何到來的請求,無論是螢幕請求,還是服務請求或事件請求,都要經過controller.xml的處理,然後轉交給相應的部分處理。 例子:  
<request-map uri="main">  
<security https="true" auth="true" />   
<response name="success" type="view" value="main" />
</request-map>   
<view-map name="main" type="screen"   page="component://accounting/widget/CommonScreens.xml#main" />
  (當請求"main"到來時,在controller.xml中,先找到<request-map uri="main">,根據其value="main",繼續向下找到view-map name="main" ,最後得到該請求該返回的頁面位置:page="component://accounting/widget /CommonScreens.xml#main" )  在OFBiz中,是根據模組-請求-服務-頁面的總體流程來實現的,每個模組的配置檔案如下:
<?xml version="1.0" encoding="UTF-8"?>
<ofbiz-component name="basicconfig"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd">
    <resource-loader name="main" type="component"/>
    <classpath type="jar" location="build/lib/*"/>
    <classpath type="dir" location="config"/>
    <entity-resource type="data" reader-name="main" loader="main" location="data/BasicDataTypeData.xml"/>
    <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/>
    <service-resource type="model" loader="main" location="servicedef/services_consultant.xml"/>
    <webapp name="basicconfig"
            title="BasicConfig"
            description="BasicConfigDescription"
            server="default-server"
            base-permission="OFBTOOLS,BASICCONFIG"
            location="webapp/basicconfig"
            mount-point="/basicconfig"
            app-bar-display="true">
    </webapp>

</ofbiz-component> 
其中涉及到 實體模型檔案,服務模型檔案,webapp宣告部分。

OFBiz中的服務

其中的服務實現有兩種,其中src對應其中的java類,此時宣告service的engine為java,而沒有使用OFBiz中自帶的特殊服務型別,下面就是服務宣告部分:
<service name="createConsultant" engine="java"
             location="com.xxx.basicconfig.service.ConsultantServices" invoke="createConsultant" auth="true">
        <description>Get commission receiving parties and amounts for a product. &lt;br/&gt;
            amount input is for the entire quantity. &lt;br/&gt;&lt;br/&gt;
            Returns a List of Maps each containing &lt;br/&gt;
            partyIdFrom String commission paying party &lt;br/&gt;
            partyIdTo String commission receiving party &lt;br/&gt;
            commission BigDecimal Commission &lt;br/&gt;
            days Long term days &lt;br/&gt;
            currencyUomId String Currency &lt;br/&gt;
            productId String Product Id &lt;br/&gt;
            Will use the virtual product if no agreement is found for a variant product. If no quantity is specified,
            defaults to one (1).
        </description>
        <!--<permission-service service-name="acctgCommissionPermissionCheck" main-action="VIEW"/>-->
        <attribute name="consultantName" type="String" mode="IN" optional="false"/>
        <attribute name="consultantCode" type="String" mode="IN" optional="false"/>
        <attribute name="consultantEmail" type="String" mode="IN" optional="false"/>
        <attribute name="consultantGender" type="String" mode="IN" optional="false"/>
        <attribute name="consultantCity" type="String" mode="IN" optional="false"/>
        <!--<attribute name="commissions" type="List" mode="OUT" optional="false"/>-->
    </service>
  其中涉及到了服務名稱,引擎型別(java),如果引擎是java類,location就使用了對應的Java類完整路徑,invoke中指定了該型別呼叫的方法。 屬性列表中聲明瞭該服務所輸入/輸出的所有的引數列表,如果在呼叫該服務時,引數並沒有滿足要求,比如名稱,型別,輸入(IN)且optional=false的引數沒有傳過來,則會報錯。 服務類的方式採用型別的靜態方法(保證無狀態),其實現舉例如下:
public static Map<String, Object> deleteConsultant(DispatchContext dispatchContext, Map<String, Object> context) {
        String consultantId = (String) context.get("userId");
        Delegator delegator = dispatchContext.getDelegator();
        GenericPK dsConsultant = delegator.makePKSingle("UserLoginSecurity", consultantId);

        try {
            delegator.removeByPrimaryKey(dsConsultant);
        } catch (GenericEntityException e) {
            Debug.logWarning(e.getMessage(), module);
            return ServiceUtil.returnError(e.getMessageList());
        }
        return new HashMap<>();
    }
   在Map結構的Context中,根據key(也就是service檔案中宣告的屬性名稱,mode需為IN/INOUT)來拿到其對應的值,返回一個Map,其中的key對應service檔案宣告的屬性,mode對應OUT,需要將該名稱的屬性值放到Map中。 在服務實現中無可避免地需要使用資料層服務,這個時候,就需要dispatchContext.getDelegator()方法來拿到Delegator作為資料端的代理,使用OFBiz中的資料模型服務來操縱資料庫。關於Delegator以及資料服務端,在下一篇總結中介紹。