• 233.44 KB
  • 2022-04-22 13:37:02 发布

基于OFBiz的电子商务平台开发毕业论文.doc

  • 38页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'基于OFBiz的电子商务平台开发毕业论文目录第一章ofbiz概述2第一节ofbiz结构2第二节项目的安装:4第三节简单的例子4第四节做一些复杂的ui7第二章ofbiz中使用groovy9第一节groovy是什么9第二节groovy基础10第三章服务和事件(minilang)18第一节什么是Minilang18第二节定义简单的Service18第二节简单的方法19第二节简单的事件20第四章实体和服务22第一节实体数据模型22第二节beanshell25第五章综合实例25第一节目录结构26第二节相关配置说明26第二节相关数据文件说明29第二节业务逻辑31第二节屏幕的创建33结束语35谢辞36参考文献37 第一章ofbiz概述第一节ofbiz结构OFBiz的宗旨,还是使用一系列自创的开源技术,开发大规模的企业级应用程序。它的目标,不是工作流,也不是appfuse这样一个整合其他开源技术的演示性的网站,而是一个综合的、企业级的电子商务网站。(一)ofbiz结构该结构去掉了些linux的文件,比如debian文件夹和后缀为.sh的脚本。该项目可以直接导入到eclipse中,集成了ant工具,可以使用相关的命令进行操作。2012/11/0722:4418,235.classpath2012/03/1810:372,229.gitignore2009/03/0507:06636.hgignore2010/03/1718:28499.project2010/09/1519:571,373ant2010/09/1519:571,153ant.bat2009/04/1423:015,984APACHE2_HEADER2013/01/1410:53applications2012/03/1810:3753,115build.xml2010/09/1519:576,969common.xml2013/01/1410:55framework2013/01/1410:55hot-deploy2010/08/3110:031,318ij.ofbiz2011/03/0117:512,155ivy.xml2010/04/0709:113,998KEYS2013/01/1410:55lib2012/11/0722:44163,481LICENSE2011/03/1316:258,271macros.xml2011/05/0223:152,283mergefromtrunk.bat2011/04/2220:5117,759NOTICE2011/01/1316:005,147ofbiz.aptana.js.format.xml 2010/10/1812:568,959OPTIONAL_LIBRARIES2010/09/0923:324,172rc.ofbiz2012/05/2020:003,492README2011/12/2913:411,127revert.bat2013/01/1410:568revision-of-11.04.02.txt2013/01/1410:52runtime2013/01/1410:55specialpurpose2010/09/0923:322,709startofbiz.bat2010/09/0923:322,713startofbizBoth.bat2010/09/0923:322,712startofbizPos.bat2013/01/1410:52themes2013/01/1410:55toolsapplications目录,包含了OFBIz核心的应用程序组件,如订单管理,电子商务存储等。component-load.xml文件配置需要载入哪几个应用程序组件。这里的每一个组件,都是一个基于OFBIZ构建的Web应用程序。framework框架目录,包含OFBIZ框架的组件,例如实体引擎和服务引擎。这是OFBIZ框架的核心。其他应用程序都是基于它来构建的,component-load.xml文件配置需要载入哪几个框架组件。(一)ofbiz框架简介整体采用3层架构用户接口,逻辑和数据,在设计一些用户用例时推荐从底部到顶部的实现,这样能够在心中明白应用程序整体的架构,允许你使用ofbiz的工具在高层模块使用低层模块的架构。1.定义实体(Entities):ofbiz-component.xml,每一个主件(component)中实体和服务的定义,类路径和web的根路径都和该配置文件相关联2.数据层DataLayer数据层的最佳实践就是使用ofbizEntityEngine(ofbiz实体引擎),绝大多数情况下实体引擎会处理99%的数据库的交互问题,如果不能处理就可以使用jdbc来进行处理。3.表现层模板 最佳的实践就是HTML或者是使用freemaker,推荐使用freemaker,它能够更好的和ofbiz核心框架工具进行结合,一般来说推荐不直接使用freemaker而是使用ofbizscreenwidget,目的是为了让action能和screens相关联。表现层模板应该尽可能简化,一些公共的内容比如header,footer,导航条,这些应该在允许时使用适配者模式进行加载,修饰每一页的模板文件应该在screen的定义xml中指定。第二节项目的安装:该项目集成了ant,可以通过ant进行安装,将项目解压出来后会看到build.xml,定位到这个xml文件的目录下也就是项目的根路径,输入命令ant,会安装一个数据集demo,该demo中包含了很多完整的例子,包括供应商,仓库,以及商店等完整供应链的流程Ø命令:antrun-install,会安装一些数据库和提取准备好的后端给用户,但是没有默认的商店和账号被创建。Ø命令:antrun-install-extseed,会创建一个管理员的账号。Ø命令:antcreate-admin-user-login,执行ofbiz,完成ofbiz的构建和配置。Ø命令:antrun,执行完成后就可以在浏览器里输入。https://localhost:8443/myportal/control/main/登陆时的默认账号是admin密码是ofbiz,该端口号的配置位于/ofbiz/framework/base/config/both-containers.xml第三节简单的例子简单在页面上输出1行文本,这个例子将会演示如何创建和加载你自己的组件,增加一个screen(view)来显示文本"thisispracticeapplication"。(一)创建一个组件在项目根路径的hot-deploy文件夹下创建1个practice文件夹hot-deploy/practice,该文件夹的名字和新创建的组件名是对应的,ofbiz-component.xml文件如下对ofbiz-component.xml的说明:该文件的作用就告诉ofbiz哪些资源会被加入到类路径里,name的值会是任意字符串,type告诉ofbiz我们将会加载1个组件。在里Øname:-定义web应用程序的名字。Øtitle:-显示在浏览器选项卡上的名字。Øserver:-使用什么服务。Øbase-permission:-需要用户拥有OFBTOOLS的权限才能使用该程序,admin用户有这个权限,所以就没有单独创建新的用户。Ølocation:-指定服务器默认的根路径。Ømount-point:-用于访问资源的url.在这个例子中应该是localhost:8080/practice。Øapp-bar-display:-让ofbiz知道是否我想要自己的主件在在主应用程序的选项卡中显示,成为公共ofbiz修饰的一部分。(一)创建webapp创建文件夹webapp,目录结构(hot-deploy/practice/webapp),该文件夹包含了所有webapp想关联的文件以及所创建的component。其中hot-deploy时热部署目录,系统在加载完application和framework后就会自动加载热部署目录里的文件。在创建文件夹"practice"在webapp下,目录结构(hot-deploy/practice/webapp/practice),一个component可以有多个app,比如webapp的创建是遵循的j2ee的标准,在创建文件夹"WEB-INF"(hot-deploy/practice/webapp/practice/WEB-INF)一个ofbiz的web应用程序需要两个配置文件controller.xml和aweb.xml。Øcontroller.xml文件告诉ofibz不同的访问者不同的请求,使用哪一个action,转到哪一个页面。Øweb.xml告诉ofbiz哪些资源是可用的比如数据库和业务逻辑的访问,如何处理web相关的问题,比如欢迎页welcomepages,重定向和错误页。这些xml可以从其他存在的component中拷贝,重要的值得改变,thelocalDispatcherName,themainDecoratorLocationandthewebSiteId.比如webSiteIdPRACTICEAuniqueIDusedtolookuptheWebSiteentitytogetinformationaboutcatalogs,etc.localDispatcherNamepracticeAuniquenameusedtoidentify/recognizethelocaldispatcherfortheServiceEnginemainDecoratorLocationcomponent://practice/widget/CommonScreens.xmlThelocationofthemain-decoratorscreentouseforthiswebapp;referredtoasacontextvariableinscreendefXMLfiles. 把webSiteId参数的值改为"PRACTICE",把mainDecoratorLocation参数的值改为component://practice/widget/CommonScreens.xml这个位置是主要的修饰文件的。${parameters.mainDecoratorLocation}这样做增加了代码的独立性,改变相关路径,就可以和之前使用过的screens一起工作,增加了代码的重用性,把存在的screens用于其他的component。创建一个新文件夹"error"(hot-deploy/practice/webapp/practice/error)创建error.jsp该文件可以从其他项目中拷贝。在controller.xml文件中指定错误页。在你的组件目录practice中创建一个"widget"(hot-deploy/practice/widget).这个目录就包含forms,menus,andscreens,用来处理用户界面的。通过命令行输入下面:java-Xmx256M-jarofbiz.jar(the-Xmx256M命令仅保证程序有足够的内存)。然后在浏览器上点击这个地址https://localhost:8443/practice/control/main第四节做一些复杂的ui(一)创建decorator在这个应用中为screens创建decorator。在"widget"目录中创建一个CommonScreens.xml。这个文件包括公用screens,用来贯穿整个应用。一个公用screen可以有一个header和footer被包含以便任意其它screens能用它作修饰器也同样有这些项。这些你可以参考"example"组件中的CommonScreens.xml文件。CommonScreens.xml文件中代码将是:     
                                                     
(二)创建一个菜单为此在你的组件的"widget"目录中创建一个PracticeMenus.xml文件。这个可以参考"example"组件的ExampleMenus.xml文件。              (一)创建子目录"actions"在WEB-INF目录中创建子目录"actions"。在这个目录中我们将创建脚本文件。脚本文件是准备数据的。这些文件将是groovy文件。以前我们是用bsh(beanshell)文件。这是用来在运行中从数据库中取数据给用户界面的脚本。工作在groovy中总是要注意导入类和包。仅导入在你文件中使用的。要从"Debug"类使用方法来放置日志消息,仅从它自己开始做起。因此在actions目录中创建一个Person.groovy,用来从实体"Person"取出所有记录。这时实际上做这些只要很少代码(一行asingleline),如下context.persons=delegator.findList("Person",null,null,null,null,false);上面的语句将从Person实体获取所有记录并通过名字persons放在context。这个列表通过名称person在ftl文件中迭代显示记录。现在在"practice"的web应用中创建一个名称为"Person.ftl"的ftl文件,用来显示从groovy文件中取来的数据。这时你仅需迭代存在context中的persons列表。仅需要如下代码Person.ftl:<#ifpersons?has_content>

Someofthepeoplewhovisitedoursiteare:


    <#listpersonsasperson>
  • ${person.firstName?if_exists}${person.lastName?if_exists}
现在在PracticeScreens.xml文件中创建一个"person"的screen,也在PracticeMenus.xml文件中创建一个新的菜单项。PracticeScreens.xml的新screen输入将是:         
                                                                                                                                                                                                                                                                                
   第二章ofbiz中使用groovy第一节groovy是什么Groovy是一种基于JVM的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy代码能够与Java代码很好地结合,也能用于扩展现有代码。由于其运行在JVM上的特性,Groovy可以使用其他Java语言编写的库。Groovy是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。Groovy是 JVM的一个替代语言(替代是指可以用Groovy在 Java 平台上进行Java编程),使用方式基本与使用Java 代码的方式相同,该语言特别适合与Spring 的动态语言支持一起使用,设计时充分考虑了Java集成,这使Groovy与Java代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。 第二节groovy基础(一)创建groovy项目New-->ProjectàJavaProject创建一个java项目。为了方便管理,建议在source中建两个source文件夹java和groovy,分别用于存储java源文件和groovy源文件:1)添加Groovy特性在项目上右击,GroovyàAddGroovyNature,这样会在项目中添加GroovyLibraries。2)添加Groovy类在项目groovy源文件下右键,NewàOtheràGroovyàGroovyClass 自动生成的源代码如下:publicclassHelloWorld{/***@paramargs*/publicstaticvoidmain(defargs){//TODOAuto-generatedmethodstub}}我们在main方法中加一句打印语句:println"HelloWorld"3)编译运行groovy类在源文件上右键,CompileGroovyFile,然后右键,RunAsàGroovy,在控制台中查看运行结果。实际上groovy语法的简练还体现在,就算整个文件中只有println"HelloWorld"这一句代码(把除这一句以外的语句删除掉吧),程序也照样能够运行。当然,为了说明groovy其实就是java,你也可以完全按照java语法来编写HelloWorld类。(二)Groovy语法简介1)没有类型的java作为动态语言,groovy中所有的变量都是对象(所有对象继承自java.lang.Object),在声明一个变量时,groovy不要求强制类型声明,仅仅要求变量名前使用关键字def(从groovyjsr1开始,在以前的版本中,甚至连def都不需要)。 修改main方法中的代码:defvar="helloworld"printlnvarprintlnvar.class你可以看到程序最后输出了var的实际类型为:java.lang.String作为例外,方法参数和循环变量的声明不需要def。1)不需要的public你可以把main方法前面的public去掉,实际上,groovy中默认的修饰符就是public,所以public修饰符你根本就不需要写,这点跟java不一样。2)不需要的语句结束符Groovy中没有语句结束符,当然为了与java保持一致性,你也可以使用;号作为语句结束符。在前面的每一句代码后面加上;号结束,程序同样正常运行(为了接受java程序员的顽固习惯)。3)字符串连接符跟java一样,如果你需要把一个字符串写在多行里,可以使用+号连接字符串。代码可以这样写:defvar="hello"+"world"+",groovy!"4)一切皆对象事实上groovy对于对象是什么类型并不关心,一个变量的类型在运行中随时可以改变,一切根据需要而定。如果你赋给它boolean,那么不管它原来是什么类型,它接受boolean值之后就会自动把类型转变为boolean值。看下面的代码:defvar="hello"+"world"+",groovy!"printlnvar;printlnvar.class;var=1001printlnvar.class输出结果:helloworld,groovy!classjava.lang.Stringclassjava.lang.Integer var这个变量在程序运行中,类型在改变。一开始给它赋值String,它的类型就是String,后面给它赋值Integer,它又转变为Integer。5)循环删除整个源文件内容,用以下代码替代: defvar="hello"+"world"+",groovy!"defrepeat(val){for(i=0;i<5;i++){printlnval}}repeat(var)输出:helloworld,groovy!helloworld,groovy!helloworld,groovy!helloworld,groovy!helloworld,groovy!注意循环变量i前面没有def。当然也没有java中常见的int,但如果你非要加上int也不会有错,因为从Groovy1.1beta2之后开始(不包括1.1beta2),groovy开始支持java经典的for循环写法。此外,上面的for语句还可以写成:for(iin0..5)这样的结果是一样的。1)String和Gstring除了标准的java.lang.String以外(用’号括住),groovy还支持Gstring字符串类型(用“号括住)。把上面的for循环中的语句改成:println"Thisis${i}:${val}"运行一下,你就会明白什么是Gstring。2)范围范围是一系列的值。例如“0..4”表明包含整数0、1、2、3、4。Groovy还支持排除范围,“0..<4”表示0、1、2、3。还可以创建字符范围:“a..e”相当于a、b、c、d、e。“a..//key,value两个参数用于接受每个元素的键/值println"$key:$value"})map.each{printlnit}//it是一个关键字,代表map集合的每个元素map.each({printlnit.getKey()+"-->"+it.getValue()})除了用于迭代之外,闭包也可以单独定义:defsay={word->println"Hi,$word!"}调用:say("groovy")say.call("groovy&grails")输出:Hi,groovy!Hi,groovy&grails! 看起来,闭包类似于方法,需要定义参数和要执行的语句,它也可以通过名称被调用。然而闭包对象(不要奇怪,闭包也是对象)可以作为参数传递(比如前面的闭包作为参数传递给了map的each方法)。而在java中,要做到这一点并不容易(也许C++中的函数指针可以,但不要忘记java中没有指针)。其次,闭包也可以不命名(当然作为代价,只能在定义闭包时执行一次),而方法不可以。1)类        Groovy类和java类一样,你完全可以用标准javabean的语法定义一个groovy类。但作为另一种语言,我们可以使用更groovy的方式定义和使用类,这样的好处是,你可以少写一半以上的javabean代码:Ø不需要public修饰符如前面所言,groovy的默认访问修饰符就是public,如果你的groovy类成员需要public修饰,则你根本不用写它。Ø不需要类型说明同样前面也说过,groovy也不关心变量和方法参数的具体类型。Ø不需要getter/setter方法不要奇怪,在很多ide(如eclipse)早就可以为序员自动产生getter/setter方法了。在groovy中,则彻底不需要getter/setter方法——所有类成员(如果是默认的public)根本不用通过getter/setter方法引用它们(当然,如果你一定要通过get/set方法访问成员属性,groovy也提供了它们)。Ø不需要构造函数不在需要程序员声明任何构造函数,因为groovy自动提供了足够你使用的构造函数。不用担心构造函数不够多,因为实际上只需要两个构造函数(1个不带参数的默认构造函数,1个只带一个map参数的构造函数—由于是map类型,通过这个参数你可以在构造对象时任意初始化它的成员变量)。Ø不需要return Groovy中,方法不需要return来返回值吗?这个似乎很难理解。看后面的代码吧。因此,groovy风格的类是这样的:Ø不需要()号Groovy中方法调用可以省略()号(构造函数除外),也就是说下面两句是等同的: person1.setName"kk"person1.setName("kk") 下面看一个完整类定义的例子:classPerson{defnamedefageStringtoString(){//注意方法的类型String,因为我们要覆盖的方法为String类型"$name,$age"}如果你使用javabean风格来做同样的事,起码代码量要增加1倍以上。我们可以使用默认构造方法实例化Person类:defperson1=newPerson()person1.name="kk"person1.age=20printlnperson1也可以用groovy的风格做同样的事:defperson2=newPerson(["name":"gg","age":22])//[]号可以省略printlnperson2 这样需要注意我们覆盖了Object的toString方法,因为我们想通过printlnperson1这样的方法简单地打印对象的属性值。然而toString方法中并没有return一个String,但不用担心,Groovy默认返回方法的最后一行的值。1)?运算符 在java中,有时候为了避免出现空指针异常,我们通常需要这样的技巧:if(rs!=null){rs.next()……}在groovy中,可以使用?操作符达到同样的目的:rs?.next()?在这里是一个条件运算符,如果?前面的对象非null,执行后面的方法,否则什么也不做。2)可变参数      等同于java5中的变长参数。首先我们定义一个变长参数的方法sum:intsum(int...var){deftotal=0for(iinvar)total+=ireturntotal}我们可以在调用sum时使用任意个数的参数(1个,2个,3个……):printlnsum(1)printlnsum(1,2)printlnsum(1,2,3)1)枚举定义一个enum:enumDay{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY}然后我们在switch语句中使用他:deftoday=Day.SATURDAYswitch(today){//SaturdayorSundaycase[Day.SATURDAY,Day.SUNDAY]:println"Weekendsarecool"break//adaybetweenMondayandFridaycaseDay.MONDAY..Day.FRIDAY:println"Boringworkday"breakdefault:println"Areyousurethisisavalidday?"}注意,switch和case中可以使用任何对象,尤其是可以在case中使用List和范围,从而使分支满足多个条件(这点跟delphi有点象)。同java5一样,groovy支持带构造器、属性和方法的enum:enumPlanet{MERCURY(3.303e+23,2.4397e6),VENUS(4.869e+24,6.0518e6),EARTH(5.976e+24,6.37814e6),MARS(6.421e+23,3.3972e6),JUPITER(1.9e+27,7.1492e7),SATURN(5.688e+26,6.0268e7),URANUS(8.686e+25,2.5559e7),NEPTUNE(1.024e+26,2.4746e7)doublemass doubleradiusPlanet(doublemass,doubleradius){this.mass=mass;this.radius=radius;}voidprintMe(){println"${name()}hasamassof${mass}"+"andaradiusof${radius}"}}Planet.EARTH.printMe()1)Elvis操作符这是三目运算符“?:”的简单形式,三目运算符通常以这种形式出现:StringdisplayName=name!=null?name:"Unknown";在groovy中,也可以简化为(因为null在groovy中可以转化为布尔值false):StringdisplayName=name?name:"Unknown";基于“不重复”的原则,可以使用elvis操作符再次简化为:StringdisplayName=name?:"Unknown"2)动态性             Groovy所有的对象都有一个元类metaClass,我们可以通过metaClass属性访问该元类。通过元类,可以为这个对象增加方法(在java中不可想象)!见下面的代码,msg是一个String,通过元类,我们为msg增加了一个String类中所没有的方法up:defmsg="Hello!"printlnmsg.metaClassString.metaClass.up={delegate.toUpperCase()}printlnmsg.up()通过元类,我们还可以检索对象所拥有的方法和属性(就象反射):msg.metaClass.methods.each{printlnit.name}msg.metaClass.properties.each{printlnit.name}甚至我们可以看到我们刚才添加的up方法。我们可以通过元类判断有没有一个叫up的方法,然后再调用它:if(msg.metaClass.respondsTo(msg,"up")){printlnmsg.toUpperCase()}当然,也可以推断它有没有一个叫bytes的属性:if(msg.metaClass.hasProperty(msg,"bytes")){printlnmsg.bytes.encodeBase64()} 第三章服务和事件(minilang)第一节什么是MinilangMinilang的语法简单的说就是已经格式好的xml,开发者在写xml时遵循一定的所定义的视图,xml文件就会被框架所解析,我们因此能把xml看做是一些命令。这些xml文件通常在顶部写xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/simple-methods.xsd">尽管minilang主要是用在服务和事件,minilang也可以用来准备数据用于screen引擎。大多数的minilang的简单的用法是变量被我们所使用,它没有很明确的获取变量,但是会在环境中按照我们想要的方式替换。比如这句话将会设置fieldOne参数的值给tempMap,如果tempMap被使用,这将会被增加,如果没有被使用,将会创建Map对象并增加,值将会被增加到key为fieldOne.关于编写xml的工具,比如XMLBuddy,可以参考http://www.xmlbuddy.com。第二节定义简单的ServiceMinilang服务的定义和调用和java的service一样,能够被controller.xml中所定义的用于控制的servlet调用。下面的例子介绍了一个简单的服务来移除关于星球的评论(PlanetReviews),删除一条记录。首先打开${component:learning}widgetLearningForms.xml从Form引擎中找到PlanetReviews,这个引擎中将会显示数据库中所有的评论。在form引擎中,在更新字段元素的下增加hyperlink元素会展示一个超链接,尽管点它会出现错误,那是因为没有在request-map(controller.xml)中来处理该请求。在${component:learning}servicedefservices.xml文件中增加新的服务定义。Servicetoremoveaplanetreview通常的做法是把服务的定义放到一个单独的xml文件中,比如说返回的账单放在一个单独的文件services_returns.xml中,所以我们增加元素到父组件ofbiz-comopnet.xml文件中,让系统知道服务的定义将会被重新加载。我们能够结构化服务的定义避免很庞大的定义文件。当服务被调用时,调用者并不会关心是哪种类型的服务,可能是java文件也可能是简单的服务。只是关心正确的参数传入到服务,第二节简单的方法简单方法的xml文件位于组件的script文件夹下,在${component:learning}下创建scriptorgofbizlearninglearning,在最终的文件LearningServices.xml。在我们增加内容到LearningServices.xml之前首先确保script文件夹在类路径里,打开${component:learning}ofbiz-component.xml,增加location指定服务定义能够被解析。在LearningServices.xml增加接下来把request-map增加到controller.xml该命令会执行查询PlanetReview实体,entity-one这个查询的标准必须是主键。该句代码定价于java代码。GenericValuelookedUpValue=delegator.findByPrimaryKey("PlanetReview",UtilMisc.toMap("reviewId",reviewId));尽管看到minilang没有那么复杂,它极大程度上的简化了java代码,在java代码中delegator从DispatchContext中获取,reviewId从context中获取方法的调用包在try/catch中。第二节简单的事件 我们调用minilang的事件,同样的方式能在controller.xml中调用java的事件,这个事件会告诉控制的servlet如何通过增加元素来处理事件。调用简单事件会执行准备和验证通过xhtml的form传进来的参数的集合,当一个事件被调用的时候,HttpServletRequest对象将会被传入,作为一个参数传入,对于简单的事件,增加到上下文.在同样的位置就像LearningServices.xml文件(${component:learning}scriptorgofbizlearninglearning)创建一个新文件LearningEvents.xml.增加一个元素在标签,最后,增加request-map到controller从事件被调用的地方。简单方法所做的事不仅仅是让一个消息写到logs中,而是通过这个能够调试minilang。 第四章实体和服务接下来会讲解在ofbiz中数据模型和业务逻辑的定义,如何在ofbiz中使用beanshell。第一节实体数据模型数据模型的物理实现形式是通过属性,关系,其实现可以是sql或者是对象,或者是两者的结合。ofbiz提供的实体引擎允许数据模型在高层次的抽象上实现。数据模型在xml文件中定义,ofbiz提供了一系列的api来操作实际的数据,查找,创建,更新,删除,实体引擎允许我们做:Ø数据的操作是在高层,而不是sql和java代码。Ø架构的实现是独立于现有的数据库。Ø减少了维护的代码,当应用程序需要改变时。Ø通过一系列简单的api避免了对象关系持久化的开销。Ø数据模型的基本单位是实体,接下来是关于一个人实体的定义。 实体类似于sql中的表或者是java对象,有一些可变的字段,实体引擎将会从这些定义和创建数据库的表开始,检查表是否违反了定义,如果需要的情况下就修改表。这些字段的类型会定义为通用的类型,当和sql交互时会自动转化为sql的类型,和java交互就会自动转化为java的类型。关系可以是一对一或者是多对多,也可以涉及一些参照完整性的检查(不是必须的),使用这些关系可以运行从一个实体到另一个实体,而不用记住那个键值相关联。这些键值得改变时用在关系上,就避免了直接通过应用程序来改变。注意:ofbiz可以自动生成外键的名字,但是最好还是自己指定,避免键的冲突。 第二节beanshellbeanshell是使用java的语法的一门动态的脚本语言,在ofbiz中用作视图层数据的收集,可以用作调试,测试,原型设计,事实上实体服务可以用beanshell来设计。下载和安装,在beanshell的官网下载bsh-2.0b4.jar(最新版),如果是允许桌面版直接双击该文件,如果是想在命令行中来使用beanshell,将文件bsh-2.0b4.jar加入到环境变量,如classpath设为.;%Java_Home%lib;E:bsh-2.0b4.jar;在命令行中使用命令javabsh.Interpreter显示为:bsh%当开始ofbiz时,注意到在控制台出现如下信息:Httpdstartedonport:9989Sessiondstartedonport:999023092(main)[BeanShellContainer.java:109:INFO]StartedBeanShelltelnetserviceon9989,999023093(main)[BeanShellContainer.java:110:INFO]NOTICE:BeanShellserviceportsarenotsecure.Pleaseprotecttheports这告诉我们在9990端口开启了beanshell的容器,你可以通过telnet到该端口,有所有的权限来访问ofbiz服务器。允许你测试代码和监听事件。将bshcontainer.bsh文件放在ofbiz文件夹下,能够调用source("bshcontainer.bsh");在使用的过程中会使用delegator对象来访问实体引擎,dispatcher用于运行服务,管理用户注册实体通常需要验证。实体的使用telnet到beanshell,使用delegator对象访问person实体,delegator是一个GenericDelegator对象有一些了增删查.第五章综合实例 第一节目录结构首先创建如下所示的目录结构,applications下的hello其中ofbiz-component.xml、build.xml、web.xml、controller.xml几个文件可以从任意一个模块中拷过来,再作些修改。Hello|--build|--data|--HobbiesData.xml//定义相关数据文件|--entitydef|--entitygroup.xml//定义数据库中表的结构|--entitymodel.xml//以及相关的主键,关系,和约束等|--script|--servicedef|--entitymodel.xml//定义的服务信息|--webapp|--hello|--include|--footer.ftl|--header.ftl|--WEB-INF|--controller.xml//用于控制页面跳转等|--web.xml|--main.ftl|--news.ftl|--widget|--HelloScreens.xml//前端screen文件|--build.xml|--ofbiz-component.xml//用于加载相关模块第二节相关配置说明ofbiz-component.xml 其中entity-resourcetype="model"用于加载相关的实体资源,type="data"用于记载相关的数据,service-resource用于加载相关的服务.buld.xml用于和ant进行集成时使用。增加了一个target模块。 web.xml中的上下文初始化参数entityDelegatorNamedefaultTheNameoftheEntityDelegatortouse,definedinentityengine.xmllocalDispatcherNamehelloAuniquenameusedtoidentify/recognizethelocaldispatcherfortheServiceEngineserviceReaderUrls/WEB-INF/services.xmlConfigurationFile(s)ForTheServiceDispatchercontroller.xml将相关的请求用ofbiz框架来接管。request-map和view-map的搭配使用负责页面的转发。第二节相关数据文件说明第一步是定义数据模型。我们想用户信息和他们的爱好并且查看每个人的所有爱好(或者,所有的人分享一种爱好)。数据模型是定义人员,爱好,和人员-爱好的联系。在关系型数据库中,你将定义两个table,其中一个是人员,另一个是爱好。还有定义他们之间联系的第三个表.第三个表允许一个人员关联许多爱好,反之亦然.你将定义人员和爱好的外键来约束第三个表。OFBiz工作原理也是类似.你可以定义两个实体,我们将定义HelloPerson和HelloHobby,和一个连接实体,HelloPersonHobby,并建立了它们之间的关系.他们之间关系主要是外键约束,而且不需要你自己去定义。(当外键改变,需要改变你的代码).注意:我们正在创造一个应用完全独立的数据模型来作说明.如果我们是在建立一个真正完整的应用,最好的做法是尽可能利用许多现有的OFBiz框架实体来做,而不是创造自己HelloPerson,我们将利用现有的框架OFBizParty/Person/PartyGroup这三个已有实体.定义数据模型,在hello下创建entitydef文件夹在entitydef/目录内,创建entitymodel.xml和entitygroup.xmlHelloPerson和HelloHobby各有一个主键,HelloPersonHobby有两个主键,它用来链接HelloPerson和HelloHobby.这是好的做法,让你外键关联,使调试容易,避免发生意外。外键的名称OFBiz由产生.定义这些实体在另一文件里,entitygroup.xml,这也是很重要的(但很容易忘记)。在entitydef/目录,这样OFBiz就会知道哪些数据写入数据库中,以供使用人):否则,将实体存在OFBiz的,但是当你真正尝试使用他们,你会得到这个错误:org.ofbiz.entity.GenericEntityException:Helpernamenotfoundfor entityHelloPerson最后,你必须增加这一行到你的ofbiz-component.xml中的,这样让OFBiz知道这个实体是应用程序的一个组件entitymodel.xml对应数据库中的3张表。 用名称是实体("HelloHobby"在我们的情况)的标签名称,使用名称的领域要么属性或作为内标签(见上次值为"葡萄酒"你的属性可以是属性的数值或内部的标签的值,如果你有很长的数值在CDATA段落里面是最好的.另外,主键不须大写或隔着_,但在其他OFBiz的应用程序这是一个规范.现在你准备加载例子数据.到WebTools主界面,你会看到链接的"XMLImport".点击"XMLImport",并于下一个画面,它会提示你文件夹的名称,在你的OFBiz中的路径.我通常不点击任何复选框和仅仅是"Import".如果你是成功的,同一个介面底部会告诉你,有多少数据添加:HobbiesData.xmlWine除了增加你的属性和数据之外,当你的数据被创建并且被更新时,OFBiz自动地创建了时间戳,这是为了横跨OFBiz多个事例同步数据。最后,如果你增加这个命令到你的ofbiz-component.xml文件,在安装过程期间OFBiz可以自动地安装你的例子数据:OFbiz实际上让你定义数据是否有“例子数据”,这样为你的app可以展示,例子数据仅仅是展示用的。第二节业务逻辑即然我们已经定义了数据模型,我们可以写一种简单的应用以delegator直接地访问实体。这是OFBiz应用程序的标准操作,但是,做为业务逻辑的分层:新建,更新和删除。 delegator直接地为查找数据使用,如更加复杂的查寻。创建业务逻辑的过程是有二步。首先,你定义了通用的业务逻辑在XML文件(使用class和方法或者脚本),来告诉OFBiz业务逻辑引擎你的参数和位置,第二,你实现服务可以用java,OFBizminilang,或者另一种脚本语言。业务逻辑通常定义在一个servicedef/目录里面,并且包括一个或更多services.xml文件。这我们的services.xml文件:注意services.xml是参考实体执行。同时直接地与标签执行。这些自动属性标签保存你时间并且使你的应用更加容易维护。你在你的ofbiz-component.xml也会需要参考service资源。另外,你必须创建并告诉它在哪里的ofbiz-component.xml装载apps。这就是为什么我们的ofbiz-component文件看起来相似,在增加classpaths以后,实体体定义、service定义和例子数据:现在它是否看起来和其他ofbiz-component.xml很相似?现在创建services。AJavaservice流行的写法是在你的应用的src/目录里面被写的:一个公共的class有两个参数的公开静态方法,DispatchContext为得到一个对象是你输入参量的delegators,dispatchers,locale,andsecurity,和称上下文的map并且退回结果map:Javaservices也将需要编译,需要适当的classpaths的知识为其他OFBizapps。这可以使用ant并且build.xml构建脚本,当然你可以从另一种应用通常复制。它是在所有OFBiz应用和框架中一个相当长的标准文件,因此我这里不会包括它。当写你的service和创造build.xml脚本,你能建立你的象这样的Javaservice:构建过程基本上采取了在src/目录的所有您的文件,编译了他们并且把他们放入构建或lib目录。Minilang比较起来是简单的。简单的minilangservice在script/目录里面并且是一个XML文件。由于它是专门为共同的OFBiz应用任务设计,例如查寻数据,存放数据,检查premissions,并且与现有的实体一起使用,并且执行业务逻辑,它使那些任务工作非常容易:最后,测试它,重新启动OFBiz装载所有新的定义在ofbiz-component.xml和services.xml。然后,打开beanshell窗口并且测试我们的service(注意:您首先应该下载bshcontainer.bsh并且把它放入在你的ofbiz/目录)这里,beanshell称执行service的服务调度员,他们是成功的,因此正确的数据被创建。(当然,它实际上采取了大约六次尝试,但我不会和你谈论细节使你不耐烦。)那么现在你创造了数据模型和service为他们。下一个步骤将放他们入Web应用程序。services.xmlHelloServices createahelloPersoncreateassss第二节屏幕的创建OFBizscreen-widget使用汇集复杂页与显示元件许多更小的片断。(如果您使用了OFBiz的更早的版本,它替换JPublish和regions框架。)第一步将在您的webapp并且创建includes/目录和文件header.ftl、footer.ftl。如果您想要使用通用的stylesheet和graphics,这是使用它最好的地方。您也可以想要从main.ftl去除同一个代码:第二步使用screen-widget并把他们拼接起来。在hello2/里面的webapp/旁边创建一个widget/目录。在widget/里面,创造一个XML文件定义你的页面:HelloScreens.xml。
最简单的screen定义是把几个ftl页面汇集到一起:最后一步,是在你的控制器中关联screen的定义而不是直接使用Freemarker模板。 结束语完成情况:从学习框架的前端技术到业务逻辑层到数据层。基本掌握了相关技术,将框架成功运行起来。所得收获:掌握了前端表现层模板freemaker,掌握了业务逻辑层相关技术beanshell,groovy,minilang,掌握了实体引擎,服务引擎的用法。掌握了框架的调试技术,在日志文件中查找相关错误。 谢辞参考文献[1]李钟尉主编,java从入门到精通,清华大学出版社,2011.12.[2]蒲子明主编,struts2+hibernate+spring整合开发.清华大学出版社:2010.10.[3]javascript高级程序设计.MicholasC.Zakas主编:人民邮电出版社,2010:.[4]JavaEE编程技术.郝玉龙编著.清华大学.北京交通大学出版社,2011.9:.[5]马雪英.大型数据库管理系统技术.应用于实例分析.电子工业出版社, '