`
火乐的春天
  • 浏览: 2148 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Apache OFBiz源码解读之MVC模型

mvc 
阅读更多
节点解析
request-map

你可以将其理解为controller的配置,如果你了解或使用过struts的配置或springmvc的annotation,就会发现这个定义跟它们是很相似的:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <request-map uri="createCreditCardAndPostalAddress"> 
            <security https="true" auth="true"/> 
            <event type="service" path="" invoke="createCreditCardAndAddress"/> 
            <response name="success" type="request" value="finalizeOrder"/> 
            <response name="error" type="view" value="billsetting"/> 
        </request-map> 


该元素定义了请求的映射关系。它使用名为uri的属性,表述该uri将要映射的请求。内部包含三个常用的子元素,分别是:security,event,response。

    security:表示该uri应该对应的安全级别(是否应该是https的,是否要进行权限检查)
    event:该请求触发的事件,这个后面在讲解handler的时候再谈
    response:指定响应的配置

view-map
一个常见的view-map配置:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <view-map name="billsetting" type="screen" page="component://order/widget/ordermgr/OrderEntryOrderScreens.xml#BillSettings"/> 


包含的属性:

    name:当前view-map的名称,通常被<request-map>子元素<response>的value属性引用
    type:其表示用什么技术展示视图,通常为screen,该值其实引用的是后面要讲解的handler
    page:指定真实用于前端展示的视图布局文件

handler
在 OFBiz中大致会划分两种类型的handler:event和screen。其实个人认为此处将handler理解为engine更为贴切一点,因为叫 handler很容易跟业务联系到一起,而如果称之为engine则可以完全跟业务隔离开来,它只是纯技术组件而已。看看handler的定义就很容易理 解了:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <!-- event handlers --> 
        <handler name="java" type="request" class="org.ofbiz.webapp.event.JavaEventHandler"/> 
        <handler name="soap" type="request" class="org.ofbiz.webapp.event.SOAPEventHandler"/> 
        <handler name="xmlrpc" type="request" class="org.ofbiz.webapp.event.XmlRpcEventHandler"/> 
        <handler name="service" type="request" class="org.ofbiz.webapp.event.ServiceEventHandler"/> 
        <handler name="service-multi" type="request" class="org.ofbiz.webapp.event.ServiceMultiEventHandler"/> 
        <handler name="service-stream" type="request" class="org.ofbiz.webapp.event.ServiceStreamHandler"/> 
        <handler name="simple" type="request" class="org.ofbiz.webapp.event.SimpleEventHandler"/> 
        <handler name="groovy" type="request" class="org.ofbiz.webapp.event.GroovyEventHandler"/> 
        <handler name="rome" type="request" class="org.ofbiz.webapp.event.RomeEventHandler"/> 
        <handler name="script" type="request" class="org.ofbiz.webapp.event.ScriptEventHandler"/> 
     
        <!-- view handlers --> 
        <handler name="screen" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/> 
        <handler name="screenxml" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/> 
        <handler name="screentext" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/> 
        <handler name="screencsv" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/> 
        <handler name="screenfop" type="view" class="org.ofbiz.widget.screen.ScreenFopViewHandler"/> 
        <handler name="jsp" type="view" class="org.ofbiz.webapp.view.JspViewHandler"/> 
        <handler name="ftl" type="view" class="org.ofbiz.webapp.ftl.FreeMarkerViewHandler"/> 
        <handler name="http" type="view" class="org.ofbiz.webapp.view.HttpViewHandler"/> 
        <handler name="birt" type="view" class="org.ofbiz.birt.webapp.view.BirtViewHandler"/> 


handler包含的属性:

    name:指定handler的名称,通常会被<request-map>子元素的event的type属性以及<view-map>的type属性所引用
    type:有两种取值:request和view。request应对的是<request-map>中的event的处理器;view对应的是<view-map>的处理器
    class:指定当前处理器实现类的完全限定名

mvc串接
下面我们以OFBiz收到一个请求为示例,展示其利用MVC模型处理请求的完整过程:
首 先我们假设OFBiz web container收到请求:createCreditCardAndPostalAddress。然后OFBiz会根据每个app下面的 controller配置文件中request-map定义,查找并匹配uri为createCreditCardAndPostalAddress的映 射节点(就是上文中讲解request-map使用的节点)。
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <request-map uri="createCreditCardAndPostalAddress"> 


然后根据其子元素security的配置,对其进行安全检查:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

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


因为有event元素,那么此处会触发一个“事件”(注意,不一定会有event元素)。这里是通过ofbiz的ServiceEngine来调用一个service:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <event type="service" path="" invoke="createCreditCardAndAddress"/> 


调用完该service后,根据service执行的结果,匹配不同的响应视图:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <response name="success" type="request" value="finalizeOrder"/> 
    <response name="error" type="view" value="billsetting"/> 


这里(也是通常情况下)有两种不同的响应配置:success,error。而且他们的响应方式不同,我们分开来看:

如 果event触发调用createCreditCardAndAddress服务的返回结果为success,那么将触发一个请求(type为 request表示再次触发一个请求,但这个请求是服务端的请求,有点像servlet里的forward动作),uri为 finalizeOrder(它是另一个request-map的定义):
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <request-map uri="finalizeOrder"> 


其语义为:完成订单创建。

如 果event触发调用createCreditCardAndAddress服务的返回结果为error,那么它将会向浏览器展示一个视图(type为 view),而该视图的名称为:billsetting。那接下来ofbiz就去查找名为:billsetting的view-map,查找到如下的结 果:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <view-map name="billsetting" type="screen" page="component://order/widget/ordermgr/OrderEntryOrderScreens.xml#BillSettings"/> 


发 现它是一个widget配置(type为screen表示OFBiz中采用的一种xml的widget),而该配置的路径 为:component://order/widget/ordermgr/OrderEntryOrderScreens.xml文件中名称为 BillSettings的screen。然后就利用名为screen的handler,来解析该screen配置:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <handler name="screen" type="view" class="org.ofbiz.widget.screen.MacroScreenViewHandler"/> 

screen

上面提到ofbiz在渲染视图的时候,采用了一个元素名为screen的配置:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <screen name="BillSettings"> 
        <section> 
            <actions> 
                <set field="stepTitleId" value="OrderOrderEntryPaymentSettings"/> 
                <set field="stepLabelId" value="AccountingPayment"/> 
                <script location="component://order/webapp/ordermgr/WEB-INF/actions/entry/BillSettings.groovy"/> 
            </actions> 
            <widgets> 
                <decorator-screen name="CommonOrderCheckoutDecorator"> 
                    <decorator-section name="body"> 
                      <platform-specific> 
                            <html><html-template location="component://order/webapp/ordermgr/entry/billsettings.ftl"/></html> 
                        </platform-specific> 
                    </decorator-section> 
                  </decorator-screen> 
            </widgets> 
        </section> 
    </screen> 


这牵扯到OFBiz前端screen以及form的widget布局设计。
section

它是screen的子元素,一个screen可以包含n个section。而它可以又会由actions以及widgets元素组成。
action

在actions元素下,你可以定义若干个不同种类的action:

    label:将值绑定到label
    entity action:利用entity engine进行action操作
    set action:简单的赋值以及groovy表达式语法
    script action:调用一个groovy脚本
    service action:调用一个服务

widgets
widgets是OFBiz布局的特点之一,它可以将一个完整的html页面拆分为一个个小块的widget,最终的页面是通过widget组合而成。

这 里首先定义了一个名为:CommonOrderCheckoutDecorator的decorator-screen。所谓的decorator- screen你可以将其理解为页面的模板或者占位。比如,就一个页面而言,部分内容与空间是固定的,主要变化的是某个特定的区域。此时布局一个新页面的时 候就没必要为其每个区域都重复编写html,对于公共区域直接引用已经定义好的模板即可。

比如此处的CommonOrderCheckoutDecorator装饰器screen,其定义中,它又引用了该app的一个main-decorator:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}"> 


这 个是当前app最外层的装饰器模板。这样就形成了widget的两层嵌套关系:BillSettings引用了 CommonOrderCheckoutDecorator,而CommonOrderCheckoutDecorator又引用了main- decorator,这种嵌套关系,也同时建立了页面显示的联系。

一个通常的应用,其mainDecoratorLoaction参数可以在其web.xml中的context-param配置中找到:
[html] view plain copy print?在CODE上查看代码片派生到我的代码片

    <context-param> 
        <param-name>mainDecoratorLocation</param-name> 
        <param-value>component://order/widget/ordermgr/CommonScreens.xml</param-value> 
        <description>The location of the main-decorator screen to use for this webapp; referred to as a context variable in screen def XML files.</description> 
    </context-param> 


回到正题,在BillSettings的第一个decorator-screen:CommonOrderCheckoutDecorator,还有一个decorator-section:body,它是对内容区域的模板占位。

widget 内部拥有一个platform-specific子元素,它可以看做是一种switch-case语句。OFBiz widget 工具集没用对render html UI的方式进行限制。理论上,你可以采用任何技术来render浏览器能显示内容。在这里UI被render成HTML,而且还使用了html模板,该模 板的路径通过location属性指定。此处该模板使用的是freemarker(这也是OFBiz中用得最多的一种模板技术)。
数据绑定

就前端展现而言,除了需要有由html标签组成的模板,还需要绑定数据才能形成完整的页面。

OFBiz提供了两种绑定数据的方式:

        form-action:如果你使用form widget,绑定数据的最好方式是采用action子元素。这可以有效得帮助你增强该form的复用性。
        groovy script action:如果你使用的是freemarker模板,此时form便是由html原生标签表示,那么推荐的方式是采用groovy脚本来获取数据并绑定至模板来显示,本文所举的示例就是这种模式。
分享到:
评论

相关推荐

    apache-ofbiz-16.11.02源码+ofbiz菜鸟笔记+Apache+OFBiz+开发初学者指南

    apache-ofbiz-16.11.02.zip,ofbiz菜鸟笔记,Apache+OFBiz+开发初学者指南.chm

    Apache OFBiz Cookbook

    ### Apache OFBiz Cookbook 知识点解析 #### 一、Apache OFBiz 概述 - **定义**:Apache OFBiz(Open For Business)是一款开源的企业级应用框架,它集成了ERP(企业资源规划)、CRM(客户关系管理)以及E-...

    Apache OFBiz Development The Beginner's Tutorial

    - **获取 OFBiz 代码**:介绍如何通过 SVN 下载 OFBiz 最新版本的源码。 - **下载并安装 SVN**:SVN(Subversion)是一款流行的版本控制系统,用于管理项目代码。 - **下载 TortoiseSVN**:TortoiseSVN 是一个易于...

    Ofbiz 数据库全模型

    Ofbiz,全称为The Open For Business Project,是一个开源的企业应用框架,主要由Apache软件基金会维护。这个项目旨在提供一套全面的、可扩展的企业级应用程序解决方案,涵盖了电子商务、供应链管理、客户关系管理等...

    Ofbiz源码阅读笔记 之 请求控制篇

    ### Ofbiz源码阅读笔记之请求控制篇 #### 一、引言 本文档基于Ofbiz 10.04.02版本进行解读,旨在深入分析Ofbiz框架中的请求控制流程及其关键技术点。Ofbiz是一款开源的企业级应用框架,支持多种业务场景,包括电子...

    开源ERP-apache-ofbiz-17.12.07.zip

    Apache OFBiz 是用于企业流程自动化的开源产品,包括 ERP(企业资源规划)、CRM(客户关系管理)、电子商务/电子商务、SCM(供应链管理)、MRP(制造资源规划)、MMS / EAM(维护管理系统/企业资产管理)的框架组件...

    Apache.OFBiz.Development

    根据给定的文件信息,以下是关于Apache OFBiz开发的知识点: 1. OFBiz介绍与安装:OFBiz是一个开源的企业自动化软件套件,它提供了构建企业应用程序所需的各种功能,比如电子商务、订单处理等。文件中提到了2008年...

    Apache OFBiz Datamodel 2

    Apache OFBiz Datamodel 2

    Apache+OFBiz+开发初学者指南

    Apache OFBiz是一个全面的企业应用程序框架,专为自动化各种业务流程而设计。它是开源社区的产物,提供了一套灵活且可扩展的组件,用于构建和管理电子商务、供应链、CRM(客户关系管理)、ERP(企业资源规划)等解决...

    Apache OFBiz Development The Beginners Tutorial

    学习Opentaps和Ofbiz的经典入门!

    Apache OFBiz Datamodel 4

    综上所述,Apache OFBiz Datamodel 4 提供了一个强大且灵活的数据模型来支持复杂的企业业务需求。通过上述详细的概念和实体介绍,我们可以更好地理解其内部结构和运作机制,进而有效利用这些功能来提升业务效率和...

    Ofbiz数据模型查询手册

    《Ofbiz数据模型查询手册》是一本专注于Apache Ofbiz系统的数据模型查询指南,它为开发者提供了深入了解Ofbiz数据库结构和查询方法的宝贵资料。Apache Ofbiz是一个开源的企业级应用框架,广泛应用于电子商务、供应链...

    Apache OFBiz Datamodel 3

    Apache OFBiz Datamodel 3 是一个高级的数据模型系统,主要用于管理电子商务、供应链管理等业务场景下的数据流与数据结构。OFBiz 本身是一款开源的企业级应用框架及应用项目,提供了一系列模块化、可扩展的组件来...

    opentaps (from apache ofbiz) 架构图 (chart of architecture)

    **OpenTaps与Apache OfBiz架构详解** OpenTaps(Open Source Total Appliance for Professional Services)是一款基于Apache OfBiz的企业级开源商务套件,旨在提供全面的企业应用解决方案,包括CRM(客户关系管理)...

    ofbiz资料大全

    Apache+OFBiz+开发初学者指南.rar OFBiz开发快速入门.rar OFBiz-技术文档.rar OFBiz API中文版.rar Apache OFBiz Cookbook Sep 2010.rar Opentaps widget使用说明.rar OFBiz.Development.2008.rar Groovy中文...

    Getting Started with Apache OFBiz Manufacturing.pdf )

    ### Apache OFBiz 制造与 MRP 入门详解 #### 引言 Apache OFBiz 制造与 MRP(物料需求计划)是一款高度集成的应用程序,为制造型企业提供了全面的功能支持,帮助其实现高效、成功的运营。该文档旨在帮助初学者快速...

    Apache+OFBiz开发指南.chm

    Apache+OFBiz开发指南.chm,跟大家分享。

Global site tag (gtag.js) - Google Analytics