基于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概貌

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被填充,显示数据。

模板中有一些脚本变量被来自于实体引擎或者服务的数据代替,

这样,最终的界面就出来的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值