??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲日韩精品无码专区加勒比☆,亚洲日本中文字幕天天更新,鲁死你资源站亚洲avhttp://www.tkk7.com/persister/category/37332.htmlzh-cnMon, 13 Sep 2010 08:02:06 GMTMon, 13 Sep 2010 08:02:06 GMT60OFBiz的MVC框架http://www.tkk7.com/persister/archive/2010/08/27/253196.htmlpersisterpersisterFri, 27 Aug 2010 14:32:00 GMThttp://www.tkk7.com/persister/archive/2010/08/27/253196.htmlhttp://www.tkk7.com/persister/comments/253196.htmlhttp://www.tkk7.com/persister/archive/2010/08/27/253196.html#Feedback0http://www.tkk7.com/persister/comments/commentRss/253196.htmlhttp://www.tkk7.com/persister/services/trackbacks/253196.htmlOFBiz是一个非常强大的企业架构体系Q这里只描述它MVC斚w的内容,从MVC的角度去看,OFBiz采用的是Service to Worker模式Q大名鼎鼎的Struts 1采用的也是这U架构。Service to Worker模式的目标就是维护ActionQView和Controller之间的分R?br />
Controller

ControlServlet?a >Front ControllerQ? 接收所有的hQ是h的入口,执行一些的预备处理后,交由RequestHandlerd理实际的h工作QView层的处理交给 ViewHandlerq行处理QViewHandler有很多实现类Q还可以自定义,可以集成很多面层显C技术,如JSP和FreeMarker{, 处理程如下图所C:


MVC的解耦的地方是通过controller.xml配置文g实现的,配置文g如下所C:

<request-map uri="login">
        
<security https="false" auth="false"/>
        
<event type="java" path="com.xxx.ldap.LdapLoginWorker" invoke="login"/>
        
<response name="success" type="view" value="main"/>
        
<response name="error" type="view" value="login"/>
</request-map>

<view-map name="main" type="screen" page="component://xxx/widget/CustomerScreens.xml#main"/>

<view-map name="login" type="screen" page="component://xxx/widget/CommonScreens.xml#login"/>

request-map的response元素有一个属性nameQ这个name理论上可以Q意选取Q不qOFBiz内置了success? errorq两个|q类gStruts 2。属性type如果是view表示得到一个页面,value值对于view-map中的name属性倹{之所以不直接写上面Q而是增加view- mapQ一是ؓ了解耦,二是针对不同的viewQ可以设|不同的type{属性。type属性很关键Q正是这个属性帮助OFBiz集成不同的显C层技术? common-controller定义了不同的type和其对应的ViewHandlerQ?/p>

    <!-- view handlers -->
    
<handler name="screen" type="view" class="org.ofbiz.widget.screen.ScreenWidgetViewHandler"/>
    
<handler name="screenfop" type="view" class="org.ofbiz.widget.screen.ScreenFopViewHandler"/>
    
<handler name="screenxml" type="view" class="org.ofbiz.widget.screen.ScreenXmlViewHandler"/>
    
<handler name="screentext" type="view" class="org.ofbiz.widget.screen.ScreenTextViewHandler"/>
    
<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"/>

q里的name对应view map中的type。实现解耦的cM是Front Controller而是RequestHandlerQ请求代理类Q在q里负责dcontroller.xml文g中的对应关系Q根据Front Controller发送过来的hQ选择相应的业务动作进行业务更斎ͼq且选择相应的视图View去解析ƈ展示。在Service to Worker模式中,RequestHandlercȝ角色是Dispatcher?br />


View
OFBiz支持很多cd的页面展C技术,JSP/FreeMarker/Velocity/PDF/Widget{。OFBiz最常用的就是Widget?a >FreeMarker。Widget是OFBiz自己Ҏ的页面技术,好处是可以不用写Q何html和css代码可以得C个统一的完整的面Q展C的业务数据也可以轻杄获取。缺ҎQ不像FreeMarker是一个纯面技术,从request和session中得C务数据,然后直接其展示处理。Widget技术将业务数据获取和业务数据展C؜在一P后台开发h员和面设计人员不能合作分工Q甚臛_有后台设计h员才能开发OFBiz应用。OFBiz之所以设计自q面技术,与OFBiz实现ERP/CRM复杂的业务系l时分不开的。ERP/CRM业务pȝ复杂多变Q模块众多。什么样的框架能够满Lpȝ呢:一是适应业务变化Q第二适合快速开发,W三面风格能够一致。OFBiz是q样的框Ӟentityd减少一个字D,在OFBiz中只需要在entitymodel中做修改Q在输入面Q显C页面,修改面都不用做M的修改就可以看到变化Q而且业务逻辑模块也不用修改就可以对变化的字段q行l护Q非常的Easy。OFBiz适合快速开发,熟悉了OFBiz开发的人员Q开发一个Customer模块Q对用户q行增删改和复杂的查询,一个小时够,够快了吧。由于不直接操作html和css代码Q用OFBiz开发的各个模块都长得一Pq是很多设计人员期望的。言归正传,q是从技术上分析View的设计。前面说了通过实现ViewHandler接口QOFBiz集成了不同的面技术以供选择。相关的cdpd如下Q?br />
View Handler:



ViewHandler负责选择相应的RendererQ进行页面显C的准备工作,对于单的面技术如JSPQJspViewHandler直接q行处理Q不再委托给其他Rendererq行处理。AbstractViewHandler的子cMQ包含Screen字眼的Handler通常相对较复杂,见上图中下面哪些HandlerQ典型的是ScreenWidgetViewHandler?br />
View Renderer:



Renderer负责具体的显C工作?br />

未完待箋






persister 2010-08-27 22:32 发表评论
]]>
OFBiz中JOB的运行机?/title><link>http://www.tkk7.com/persister/archive/2010/02/26/313974.html</link><dc:creator>persister</dc:creator><author>persister</author><pubDate>Fri, 26 Feb 2010 03:17:00 GMT</pubDate><guid>http://www.tkk7.com/persister/archive/2010/02/26/313974.html</guid><wfw:comment>http://www.tkk7.com/persister/comments/313974.html</wfw:comment><comments>http://www.tkk7.com/persister/archive/2010/02/26/313974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/persister/comments/commentRss/313974.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/persister/services/trackbacks/313974.html</trackback:ping><description><![CDATA[OFBiz执行后台d的类在org.ofbiz.service.job中?br /> <br /> JobPoller和JobInvoker是主要的两个c,一个负责查询可以执行的JobQ另一个执行Jobd。Jobcd如下所C?br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/persister/job1.JPG" width="504" height="314" /><br /> <br /> <strong>1.Job轮询</strong><br /> <br /> 创徏JobManagerӞ会创建JobPoller的一个实例。JobPoller实现了Runnable接口Q以此创建线E后<br /> 通过JobManager一直轮询是否有Job需要执行,如果有奖其攑օ队列中?br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> run() {<br /> </span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /> </span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> wait 30 seconds before the first poll</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">            java.lang.Thread.sleep(</span><span style="color: rgb(0, 0, 0);">30000</span><span style="color: rgb(0, 0, 0);">);<br /> </span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (InterruptedException e) {<br /> </span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">        }<br /> </span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (isRunning) {<br /> </span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /> </span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> grab a list of jobs to run.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">                List</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">Job</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> pollList </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> jm.poll();<br /> </span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Debug.logInfo("Received poll list from JobManager [" + pollList.size() + "]", module);</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> (Job job : pollList) {<br /> </span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (job.isValid()) {<br /> </span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">                        queueNow(job);<br /> </span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">                        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Debug.logInfo("Job [" + job.getJobId() + "] is queued", module);</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">                    }<br /> </span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);">                }<br /> </span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> NOTE: using sleep instead of wait for stricter locking</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">                java.lang.Thread.sleep(pollWaitTime());<br /> </span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">            } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (InterruptedException e) {<br /> </span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">                Debug.logError(e, module);<br /> </span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);">                stop();<br /> </span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">            }<br /> </span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">        }<br /> </span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">    }<br /> </span><span style="color: rgb(0, 128, 128);">27</span> </div> <br /> queueNowҎ要执行job攑օ到队列中Q如果队列中的等待执行的job数量很多Q那么就创徏一定数量的U程执行q些job?br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">   </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> queueNow(Job job) {<br />  </span>2<span style="color: rgb(0, 0, 0);">         </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);"> (run) {<br /> </span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">            run.add(job);<br /> </span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">        }<br /> </span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (Debug.verboseOn()) Debug.logVerbose(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">New run queue size: </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> run.size(), module);<br /> </span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (run.size() </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> pool.size() </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> pool.size() </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> maxThreads()) {<br /> </span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);"> (pool) {<br /> </span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (run.size() </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> pool.size() </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> pool.size() </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> maxThreads()) {<br /> </span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> calcSize </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (run.size() </span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);"> jobsPerThread()) </span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> (pool.size());<br /> </span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> addSize </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> calcSize </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> maxThreads() </span><span style="color: rgb(0, 0, 0);">?</span><span style="color: rgb(0, 0, 0);"> maxThreads() : calcSize;<br /> </span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">; i </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> addSize; i</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">) {<br /> </span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);">                        JobInvoker iv </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> JobInvoker(</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">, invokerWaitTime());<br /> </span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">                        pool.add(iv);<br /> </span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);">                    }<br /> </span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">                }<br /> </span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">            }<br /> </span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">        }<br /> </span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">    }<br /> </span></div> <br /> JobInvoker是执行的线E,它从queue中取jobq执行。JobInvokerU程不是一直运行下去,q行的时间长度超q一定的|见serviceengine.xml中ttl的|U程׃停止q从pool中删除。JobInvoker的runҎ中job.exec()执行具体的Q务?br /> <br /> <br /> <strong>2.Job执行</strong><br /> <br /> Jobc都有一个execҎQ用h行Job的service。如GenericServiceJob中的execҎ如下Q?br /> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> exec() </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> InvalidJobException {<br /> </span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">        init();<br /> </span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> no transaction is necessary since runSync handles this</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /> </span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> get the dispatcher and invoke the service via runSync -- will run all ECAs</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">            LocalDispatcher dispatcher </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dctx.getDispatcher();<br /> </span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">            Map</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">String, Object</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> result </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dispatcher.runSync(getServiceName(), getContext());<br /> </span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> check for a failure</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> isError </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ModelService.RESPOND_ERROR.equals(result.get(ModelService.RESPONSE_MESSAGE));<br /> </span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (isError) {<br /> </span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">                 String errorMessage </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (String) result.get(ModelService.ERROR_MESSAGE);<br /> </span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">                 </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.failed(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Exception(errorMessage));<br /> </span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">            }<br /> </span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (requester </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br /> </span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);">                requester.receiveResult(result);<br /> </span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">            }<br /> </span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Throwable t) {<br /> </span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> pass the exception back to the requester.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (requester </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br /> </span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">                requester.receiveThrowable(t);<br /> </span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">            }<br /> </span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> call the failed method</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.failed(t);<br /> </span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);">        }<br /> </span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> call the finish method</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.finish();<br /> </span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);">    }<br /> </span><span style="color: rgb(0, 128, 128);">34</span> </div> <br /> 在执行service执行Q有一个initҎQ在PersistedServiceJobcMinitҎ主要是生成下一个执行的dQ如果有的话。也x说每一个job是由当时执行的这个job生成的,Ҏ是什么呢Q主要是两个变量QtempExprId和maxRecurrenceCountQinitҎ中:<br />     <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);">    TemporalExpression expr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br /> </span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">    ……<br /> </span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (expr </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> UtilValidate.isNotEmpty(job.getString(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">tempExprId</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">))) {<br /> </span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /> </span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">                expr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> TemporalExpressionWorker.getTemporalExpression(</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.delegator, job.getString(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">tempExprId</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br /> </span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">            } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (GenericEntityException e) {<br /> </span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> RuntimeException(e.getMessage());<br /> </span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">            }<br /> </span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">        }<br /> </span><span style="color: rgb(0, 128, 128);">11</span> </div> <br /> TemporalExpressionWorker里面有一个makeTemporalExpressionҎ很重要,从这个方法可以知道怎么配置TemporalExpression实体数据了,当然要结合TemporalExpressionsc,里面定义了各U配|的l节?br /> <br /> tempExprTypeId有如下几U:<br /> <br /> DateRange<br /> DayInMonth<br /> DayOfMonthRange<br /> DayOfWeekRange<br /> Difference<br /> Frequency<br /> Intersection<br /> MonthRange<br /> TimeOfDayRange<br /> Union<br /> <br /> 比如如果希望服务只执行一ơ,可以如下配置Q?br />     <TemporalExpression tempExprId="RUNONCE" tempExprTypeId="FREQUENCY" integer1="1" integer2="1"/><br />     <JobSandbox jobId="CurrencyRateSynAll" jobName="Currency Rate SynAll" runTime="2010-02-26 09:38:00.000" serviceName="currencyRateSynAll" poolId="pool" runAsUser="system" tempExprId="RUNONCE" maxRecurrenceCount="0"/><br /> <br /> maxRecurrenceCount="0" 表示Q不重复。tempExprTypeId="FREQUENCY" integer1="1" integer2="1"表示一q执行一ơ。所以d执行一ơ就l束了?br /> <br /> 每天都执行可以这样配|:<br /> <br /> <TemporalExpression tempExprId="MIDNIGHT_DAILY" tempExprTypeId="TIME_OF_DAY_RANGE" string1="20:00:00" string2="20:00:00"/><br />     <JobSandbox jobId="MailNotification" jobName="Mail Notification Job" runTime="2010-02-25 18:00:00.000" serviceName="mailNotificantion" poolId="pool" runAsUser="system" tempExprId="MIDNIGHT_DAILY" maxRecurrenceCount="-1"/><br /> <br /> maxRecurrenceCount="-1"表示无限循环下去。tempExprId="MIDNIGHT_DAILY" tempExprTypeId="TIME_OF_DAY_RANGE" string1="20:00:00" string2="20:00:00"/>表示每天晚上八点执行?br /> <br /> 每个月一ơQ务可以如下配|:<br /> <br /> <TemporalExpression tempExprId="ONCEINMONTH" tempExprTypeId="FREQUENCY" date1="2010-02-26 11:05:00.000" integer1="2" integer2="1"/><br />     <JobSandbox jobId="CurrencyRateSyn" jobName="Currency Rate Syn" runTime="2010-02-26 11:05:00.000" serviceName="currencyRateSyn" poolId="pool" runAsUser="system" tempExprId="ONCEINMONTH" maxRecurrenceCount="-1"/><br /> <br /> tempExprTypeId="FREQUENCY" date1="2010-02-26 11:05:00.000" integer1="2" integer2="1"表示每月一ơ,旉是date1定义的时_如果没用定义date1Q那么就是当前时间?br /> <br /> q里的配|相当灵z,好好掌握?br />     <br /> <img src ="http://www.tkk7.com/persister/aggbug/313974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/persister/" target="_blank">persister</a> 2010-02-26 11:17 <a href="http://www.tkk7.com/persister/archive/2010/02/26/313974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OFBiz中services调用机制http://www.tkk7.com/persister/archive/2010/02/24/313799.htmlpersisterpersisterWed, 24 Feb 2010 07:19:00 GMThttp://www.tkk7.com/persister/archive/2010/02/24/313799.htmlhttp://www.tkk7.com/persister/comments/313799.htmlhttp://www.tkk7.com/persister/archive/2010/02/24/313799.html#Feedback0http://www.tkk7.com/persister/comments/commentRss/313799.htmlhttp://www.tkk7.com/persister/services/trackbacks/313799.html
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Map<String, Object> result = dispatcher.runSync(getServiceName(), getContext());

LocalDispatcher是本地调度器Q实现服务的同步异步调度和定时Q务的调度。与服务调度相关的类囑֦下:



LocalDispatcher是一个接口,实例化的都是GenericDispatcherc,ContextFilter实现了Servlet FilterQ会初始化一个GenericDispatcher,q将其存攑֜ServletContext中,以备整个应用使用?br /> 在请求处理过E中Q如果遇到service的eventQ那么EventHandler会用LocalDispatcher执行service?br /> 实际上GenericDispatcher只是一个ProxyQ自己ƈ不处理相关的调度工作Q真正最苦最累的调度工作是由ServiceDispatcher完成的。下面具体研I一下Dispatcher同步和异步调用方法的实现代码Q?br />
1.同步调用

通过dispatcher调用runSyncҎQ也x调用GenericDispatcher的runSyncҎQ?br />     
        /**
         * @see org.ofbiz.service.LocalDispatcher#runSync(java.lang.String, java.util.Map)
         */
        public Map<String, Object> runSync(String serviceName, Map<String, ? extends Object> context)
        throws ServiceValidationException, GenericServiceException
        {
            ModelService service = ctx.getModelService(serviceName);
            return dispatcher.runSync(this.name, service, context);
        }

dispatcher实际是ServiceDispatcher对象。ServiceDispatcher的runSyncҎ有三癑֤行,比较复杂Q?br /> 但最l调用service的是GenericEngine?br />
    GenericEngine engine = this.getGenericEngine(modelService.engineName);
    ……
    
    Map<String, Object> invokeResult = engine.runSync(localName, modelService, context);
  
GenericEngine是其工厂cGenericEngineFactory获取的,q个Factoryc非常简单:

public class GenericEngineFactory {

    protected ServiceDispatcher dispatcher = null;
    protected Map<String, GenericEngine> engines = null;

    public GenericEngineFactory(ServiceDispatcher dispatcher) {
        this.dispatcher = dispatcher;
        engines = FastMap.newInstance();
    }

    /**
     * Gets the GenericEngine instance that corresponds to given the name
     *@param engineName Name of the engine
     *@return GenericEngine that corresponds to the engineName
     */
    public GenericEngine getGenericEngine(String engineName) throws GenericServiceException {
        Element rootElement = null;

        try {
            rootElement = ServiceConfigUtil.getXmlRootElement();
        } catch (GenericConfigException e) {
            throw new GenericServiceException("Error getting Service Engine XML root element", e);
        }
        Element engineElement = UtilXml.firstChildElement(rootElement, "engine", "name", engineName);

        if (engineElement == null) {
            throw new GenericServiceException("Cannot find a service engine definition for the engine name [" + engineName + "] in the serviceengine.xml file");
        }

        String className = engineElement.getAttribute("class");

        GenericEngine engine = engines.get(engineName);

        if (engine == null) {
            synchronized (GenericEngineFactory.class) {
                engine = engines.get(engineName);
                if (engine == null) {
                    try {
                        ClassLoader loader = Thread.currentThread().getContextClassLoader();
                        Class<?> c = loader.loadClass(className);
                        Constructor cn = c.getConstructor(ServiceDispatcher.class);
                        engine = (GenericEngine) cn.newInstance(dispatcher);
                    } catch (Exception e) {
                        throw new GenericServiceException(e.getMessage(), e);
                    }
                    if (engine != null) {
                        engines.put(engineName, engine);
                    }
                }
            }
        }

        return engine;
    }
}

从配|文件serviceengine.xml文g中获取相应的engine子类Q如java的是org.ofbiz.service.engine.StandardJavaEngine
bsh的是org.ofbiz.service.engine.BeanShellEngine?br />
Java的StandardJavaEnignerunSyncҎ采用的是反射来执行相应的ҎQ如下:

        Class<?> c = cl.loadClass(this.getLocation(modelService));
            Method m = c.getMethod(modelService.invoke, DispatchContext.class, Map.class);
            result = m.invoke(null, dctx, context);
            
不同的Engine实现的方式不一栗?br />
2. 异步调用

异步调用怎么实现的呢Q实现异步的原理是启动一个线E来执行相应的业务逻辑Q原Ҏ直接q回Q从而实现异步。具体实现的时候可以根据实际情况而定Q比如将业务逻辑装成一个Q务,此d攑ֈ一个Q务链中,U程池采用先q先出的方式来选择dq行执行。OFBiz中怎么实现呢?具体查看GenericAsyncEngine的runAsyncҎ发现是通过一个生成一个Job来实现的Q?br />
        job = new GenericServiceJob(dctx, jobId, name, modelService.name, context, requester);
        try {
            dispatcher.getJobManager().runJob(job);
        } catch (JobManagerException jse) {
            throw new GenericServiceException("Cannot run job.", jse);
        }
对于Job的执行,感兴的可以看我的另一文?a href="http://www.tkk7.com/persister/archive/2010/02/26/313974.html">OFBiz中Job的运行机?/a>?br />



persister 2010-02-24 15:19 发表评论
]]>
OFBiz的中文ؕ码解x?/title><link>http://www.tkk7.com/persister/archive/2009/08/10/290568.html</link><dc:creator>persister</dc:creator><author>persister</author><pubDate>Mon, 10 Aug 2009 08:58:00 GMT</pubDate><guid>http://www.tkk7.com/persister/archive/2009/08/10/290568.html</guid><wfw:comment>http://www.tkk7.com/persister/comments/290568.html</wfw:comment><comments>http://www.tkk7.com/persister/archive/2009/08/10/290568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/persister/comments/commentRss/290568.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/persister/services/trackbacks/290568.html</trackback:ping><description><![CDATA[<p>OFBiz开发时遇到q的问题,MySQL数据库插入中文数据时出现了一个问题,报告中文错误Qincorrect string value Q.Q.Q?/p> <p>1.q时׃字符~码不一致导致的Q应该将数据库对应的表或coloumҎuft-8Q所以如果在CustomerExtraq表中存储中文的话,需要将<br />   此表另外q有operationlog表的charsetҎutf-8</p> <p>2.Servlet中字W显CZؓ证券的中文,而且表也讄为utf-8Q但是数据库和页面还是ؕ码,怎么回事Q?br />   q里需要修改jdbc url的参敎ͼ如将jdbc:mysql://localhost/ccbportal?zeroDateTimeBehavior=convertToNull<br />   ҎQjdbc:mysql://localhost/ccbportal?zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;characterEncoding=UTF-8</p> <p>3.前台输入的是中文Q到后台变成了qQ怎么回事Q?br />   无论何种表单提交都可以在后台的java文g中通过String des = new String(s.getBytes("iso8859-1"),"UTF-8");<br />   来{换成你想要的UTFQ?~码方式。但如果每处都加词句太麻烦,故分post和get两种方式区分提交?br />   写一个Filter卛_解决问题Q?br />   </p> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);"> import java.io.IOException;<br /> </span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);"> import javax.servlet.ServletException;<br /> </span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);"> import javax.servlet.Filter;<br /> </span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);"> import javax.servlet.FilterChain;<br /> </span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);"> import javax.servlet.FilterConfig;<br /> </span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);"> import javax.servlet.ServletRequest;<br /> </span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);"> import javax.servlet.ServletResponse;<br /> </span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);"> public class SetCharacterEncodingFilter implements Filter {<br /> </span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);">  protected String encoding = "GBK";<br /> </span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">  protected FilterConfig filterConfig = null;<br /> </span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">17</span> <span style="color: rgb(0, 0, 0);">  protected boolean ignore = true;<br /> </span><span style="color: rgb(0, 128, 128);">18</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">19</span> <span style="color: rgb(0, 0, 0);">  public void init(FilterConfig filterConfig) throws ServletException {<br /> </span><span style="color: rgb(0, 128, 128);">20</span> <span style="color: rgb(0, 0, 0);">   this.filterConfig = filterConfig;<br /> </span><span style="color: rgb(0, 128, 128);">21</span> <span style="color: rgb(0, 0, 0);">   this.encoding = filterConfig.getInitParameter("encoding");<br /> </span><span style="color: rgb(0, 128, 128);">22</span> <span style="color: rgb(0, 0, 0);">   String value = filterConfig.getInitParameter("ignore");<br /> </span><span style="color: rgb(0, 128, 128);">23</span> <span style="color: rgb(0, 0, 0);">   if (value == null)<br /> </span><span style="color: rgb(0, 128, 128);">24</span> <span style="color: rgb(0, 0, 0);">    this.ignore = true;<br /> </span><span style="color: rgb(0, 128, 128);">25</span> <span style="color: rgb(0, 0, 0);">   else if (value.equalsIgnoreCase("true"))<br /> </span><span style="color: rgb(0, 128, 128);">26</span> <span style="color: rgb(0, 0, 0);">    this.ignore = true;<br /> </span><span style="color: rgb(0, 128, 128);">27</span> <span style="color: rgb(0, 0, 0);">   else if (value.equalsIgnoreCase("yes"))<br /> </span><span style="color: rgb(0, 128, 128);">28</span> <span style="color: rgb(0, 0, 0);">    this.ignore = true;<br /> </span><span style="color: rgb(0, 128, 128);">29</span> <span style="color: rgb(0, 0, 0);">   else<br /> </span><span style="color: rgb(0, 128, 128);">30</span> <span style="color: rgb(0, 0, 0);">    this.ignore = false;<br /> </span><span style="color: rgb(0, 128, 128);">31</span> <span style="color: rgb(0, 0, 0);">  }<br /> </span><span style="color: rgb(0, 128, 128);">32</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">33</span> <span style="color: rgb(0, 0, 0);">  public void doFilter(ServletRequest request, ServletResponse response,<br /> </span><span style="color: rgb(0, 128, 128);">34</span> <span style="color: rgb(0, 0, 0);">    FilterChain chain) throws IOException, ServletException {<br /> </span><span style="color: rgb(0, 128, 128);">35</span> <span style="color: rgb(0, 0, 0);">   // Conditionally select and set the character encoding to be used<br /> </span><span style="color: rgb(0, 128, 128);">36</span> <span style="color: rgb(0, 0, 0);">   if (ignore || (request.getCharacterEncoding() == null)) {<br /> </span><span style="color: rgb(0, 128, 128);">37</span> <span style="color: rgb(0, 0, 0);">    String encoding = selectEncoding(request);<br /> </span><span style="color: rgb(0, 128, 128);">38</span> <span style="color: rgb(0, 0, 0);">    if (encoding != null) {<br /> </span><span style="color: rgb(0, 128, 128);">39</span> <span style="color: rgb(0, 0, 0);">     request.setCharacterEncoding(encoding);<br /> </span><span style="color: rgb(0, 128, 128);">40</span> <span style="color: rgb(0, 0, 0);">    }<br /> </span><span style="color: rgb(0, 128, 128);">41</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">42</span> <span style="color: rgb(0, 0, 0);">   }<br /> </span><span style="color: rgb(0, 128, 128);">43</span> <span style="color: rgb(0, 0, 0);">   // Pass control on to the next filter<br /> </span><span style="color: rgb(0, 128, 128);">44</span> <span style="color: rgb(0, 0, 0);">   chain.doFilter(request, response);<br /> </span><span style="color: rgb(0, 128, 128);">45</span> <span style="color: rgb(0, 0, 0);">  }<br /> </span><span style="color: rgb(0, 128, 128);">46</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">47</span> <span style="color: rgb(0, 0, 0);">  protected String selectEncoding(ServletRequest request) {<br /> </span><span style="color: rgb(0, 128, 128);">48</span> <span style="color: rgb(0, 0, 0);">   return (this.encoding);<br /> </span><span style="color: rgb(0, 128, 128);">49</span> <span style="color: rgb(0, 0, 0);">  }<br /> </span><span style="color: rgb(0, 128, 128);">50</span> <span style="color: rgb(0, 0, 0);"> <br /> </span><span style="color: rgb(0, 128, 128);">51</span> <span style="color: rgb(0, 0, 0);">  public void destroy() {<br /> </span><span style="color: rgb(0, 128, 128);">52</span> <span style="color: rgb(0, 0, 0);">   this.encoding = null;<br /> </span><span style="color: rgb(0, 128, 128);">53</span> <span style="color: rgb(0, 0, 0);">   this.filterConfig = null;<br /> </span><span style="color: rgb(0, 128, 128);">54</span> <span style="color: rgb(0, 0, 0);">  }<br /> </span><span style="color: rgb(0, 128, 128);">55</span> <span style="color: rgb(0, 0, 0);"> }<br /> </span><span style="color: rgb(0, 128, 128);">56</span> <span style="color: rgb(0, 0, 0);">  <br /> </span></div> <p><br /> web.xmld此FilterQ?br /> </p> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 128, 128);"> 1</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">filter</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 2</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">encodeFilter</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 3</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">filter-class</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"> com.aicent.ccb.filter.SetCharacterEncodingFilter</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">filter-class</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 4</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">init-param</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 5</span> <span style="color: rgb(0, 0, 0);">   </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">param-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">encoding</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">param-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 6</span> <span style="color: rgb(0, 0, 0);">   </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">param-value</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">GBK</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">param-value</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 7</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">init-param</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 8</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">init-param</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);"> 9</span> <span style="color: rgb(0, 0, 0);">   </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">param-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">ignore</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">param-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">10</span> <span style="color: rgb(0, 0, 0);">   </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">param-value</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">true</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">param-value</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">11</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">init-param</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">12</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">filter</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">13</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">filter-mapping</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">14</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">encodeFilter</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">filter-name</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">15</span> <span style="color: rgb(0, 0, 0);">  </span><span style="color: rgb(0, 0, 255);"><</span><span style="color: rgb(128, 0, 0);">url-pattern</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">/control/*</span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">url-pattern</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);"><br /> </span><span style="color: rgb(0, 128, 128);">16</span> <span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);"></</span><span style="color: rgb(128, 0, 0);">filter-mapping</span><span style="color: rgb(0, 0, 255);">></span><span style="color: rgb(0, 0, 0);">  <br /> </span></div> <p> </p> <img src ="http://www.tkk7.com/persister/aggbug/290568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/persister/" target="_blank">persister</a> 2009-08-10 16:58 <a href="http://www.tkk7.com/persister/archive/2009/08/10/290568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分布式事务及其在OFBiz的实?/title><link>http://www.tkk7.com/persister/archive/2009/04/19/266439.html</link><dc:creator>persister</dc:creator><author>persister</author><pubDate>Sun, 19 Apr 2009 10:01:00 GMT</pubDate><guid>http://www.tkk7.com/persister/archive/2009/04/19/266439.html</guid><wfw:comment>http://www.tkk7.com/persister/comments/266439.html</wfw:comment><comments>http://www.tkk7.com/persister/archive/2009/04/19/266439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/persister/comments/commentRss/266439.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/persister/services/trackbacks/266439.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;"><span style="font-size: 10pt;"> <strong>1、分布式事务相关概念</strong><br /> <span style="font-size: small;">分布式事务处理(Distributed Transaction ProcessingQDTPQ是指一个事务可能涉及多个数据库操作Q分布式事务处理的关键是必须有一U方法可以知道事务在M地方所做的所有动作,提交或回滚事务的军_必须产生l一的结果(全部提交或全部回滚)?/span><span style="font-family: "Courier New";"><br /> </span><span style="font-size: small;"><span style="font-family: "Courier New";"> X/Open </span>l织Q即现在?span style="font-family: "Courier New";"> Open Group </span>Q定义了分布式事务处理模型?span style="font-family: "Courier New";"> X/Open DTP </span>模型Q?span style="font-family: "Courier New";"> 1994 </span>Q包括应用程序(<span style="font-family: "Courier New";"> AP </span>Q、事务管理器Q?span style="font-family: "Courier New";"> TM </span>Q、资源管理器Q?span style="font-family: "Courier New";"> RM </span>Q、通信资源理器(<span style="font-family: "Courier New";"> CRM </span>Q四部分。一般,常见的事务管理器Q?span style="font-family: "Courier New";"> TM </span>Q是交易中间Ӟ常见的资源管理器Q?span style="font-family: "Courier New";"> RM </span>Q是数据库,常见的通信资源理器(<span style="font-family: "Courier New";"> CRM </span>Q是消息中间件?/span><span style="font-family: "Courier New";"><br /> </span><span style="font-size: small;">  通常把一个数据库内部的事务处理,如对多个表的操作Q作为本C务看待。数据库的事务处理对象是本地事务Q而分布式事务处理的对象是全局事务?/span><br /> <p style="margin: 0cm 0cm 0pt;"><span style="font-size: small;"><span>    所谓全局事务Q是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,q个工作x一个全局事务Q例如,一个事务中可能更新几个不同的数据库。对 数据库的操作发生在系l的各处但必d部被提交或回滚。此时一个数据库对自己内部所做操作的提交不仅依赖本n操作是否成功Q还要依赖与全局事务相关的其? 数据库的操作是否成功Q如果Q一数据库的M操作p|Q则参与此事务的所有数据库所做的所有操作都必须回滚?/span>  <br /> </span></p> <p style="margin: 0cm 0cm 0pt;"><span style="font-size: small;">   一般情况下Q某一数据库无法知道其它数据库在做什么,因此Q在一?span style="font-family: "Courier New";"> DTP </span>环境中,交易中间件是必需的,由它通知和协调相x据库的提交或回滚。而一个数据库只将其自己所做的操作Q可恢复Q媄到全局事务中?/span></p> <span style="font-size: small;"><span style="font-family: "Courier New";">   XA </span>是<span style="font-family: "Courier New";"> X/Open DTP </span>定义的交易中间g与数据库之间的接口规范(x口函敎ͼQ交易中间g用它来通知数据库事务的开始、结束以及提交、回滚等?span style="font-family: "Courier New";"> XA </span>接口函数由数据库厂商提供?/span><br /> <p style="margin: 0cm 0cm 0pt;"><span style="font-family: "Courier New";">   <span style="font-size: small;">XA </span></span><span style="font-size: small;">与两阶段提交协议</span></p> <p style="margin: 0cm 0cm 0pt;"><span style="font-family: "Courier New";">   </span><span style="font-size: small;">通常情况下,交易中间件与数据库通过<span style="font-family: "Courier New";"> XA </span>接口规范Q用两阶段提交来完成一个全局事务Q?span style="font-family: "Courier New";"> XA </span>规范的基是两阶段提交协议?/span><span style="font-family: "Courier New";"><br /> </span><span style="font-size: small;"><span> 在第一阶段Q交易中间gh所有相x据库准备提交Q预提交Q各自的事务分支Q以认是否所有相x据库都可以提交各自的事务分支。当某一数据库收到预 提交后,如果可以提交属于自己的事务分支,则将自己在该事务分支中所做的操作固定记录下来Qƈl交易中间g一个同意提交的应答Q此时数据库不能再在该? 务分支中加入M操作Q但此时数据库ƈ没有真正提交该事务,数据库对׃n资源的操作还未释放(处于上锁状态)。如果由于某U原因数据库无法提交属于自己? 事务分支Q它回滚自q所有操作,释放对共享资源上的锁Qƈq回l交易中间gp|应答?/span>在第二阶D,交易中间件审查所有数据库q回的预提交l果Q如所有数据库都可以提交,交易中间件将要求所有数据库做正式提交,q样该全局事务被提交。而如果有M数据库预提交q回p|Q交易中间g要求所有其它数据库回滚其操作,q样该全局事务被回滚?/span><span style="font-family: "Courier New";"><br /> </span><span style="font-size: small;">  以一个全局事务ZQ?span style="font-family: "Courier New";"> AP </span>首先通知交易中间件开始一个全局事务Q交易中间g通过<span style="font-family: "Courier New";"> XA </span>接口函数通知数据库开始事务,然后<span style="font-family: "Courier New";"> AP </span>可以Ҏ据库理的资源进行操作,数据库系l记录事务对本地资源的所有操作。操作完成后交易中间仉过<span style="font-family: "Courier New";"> XA </span>接口函数通知数据库操作完成。交易中间g负责记录<span style="font-family: "Courier New";"> AP </span>操作q哪些数据库Q事务分支)?span style="font-family: "Courier New";"> AP </span>Ҏ情况通知交易中间件提交该全局事务Q交易中间g会通过<span style="font-family: "Courier New";"> XA </span>接口函数要求各个数据库做预提交,所有数据库q回成功后要求各个数据库做正式提交,此时一W全局事务l束?/span></p> <p style="margin: 0cm 0cm 0pt;"><span style="font-family: "Courier New";">   </span><span style="font-size: small;"><span style="font-family: "Courier New";">XA </span>规范对应用来_最大好处在于事务的完整性由交易中间件和数据库通过<span style="font-family: "Courier New";"> XA </span>接口控制Q?span style="font-family: "Courier New";"> AP </span>只需要关注与数据库的应用逻辑的处理,而无需q多兛_事务的完整性,应用设计开发会化很多?/span></p> <p style="margin: 0cm 0cm 0pt;"><span style="font-family: "Courier New";">   </span><span style="font-size: small;">具体来说Q如果没有交易中间gQ应用系l需要在E序内部直接通知数据库开始、结束和提交事务Q当出现异常情况时必ȝ专门的程序对数据库进行反向操作才能完成回滚。如果是有很多事务分支的全局事务Q回滚时情况变得异常复杂。而?span style="font-family: "Courier New";"> XA </span>接口Q则全局事务的提交是׃易中间g控制Q应用程序只需通知交易中间件提交或回滚事务Q就可以控制整个事务Q可能涉及多个异地的数据库)的全部提交或回滚Q应用程序完全不用考虑冲正逻辑?/span><span style="font-family: "Courier New";"><br /> </span><span><span style="font-size: small;"> 在一个涉及多个数据库的全局事务中,Z证全局事务的完整性,׃易中间g控制数据库做两阶D|交是必要的。但典型的两阶段提交Q对数据库来说事务从开 始到l束Q提交或回滚Q时间相对较长,在事务处理期间数据库使用的资源(如逻辑日志、各U锁Q,直到事务l束时才会释放。因此,使用典型的两阶段提交相对 来说会占用更多的资源Q在|络条g不是很好Q如低速网、网l颠RJ,情况会更Z重?/span></span><span style="font-family: "Courier New";"><br /> </span><span style="font-size: small;">  当一个全局事务只涉及一个数据库Ӟ有一U优化方式,即一阶段提交。当<span style="font-family: "Courier New";"> AP </span>通知交易中间件提交事务时Q交易中间g直接要求数据库提交事务,省去两阶D|交中的第一阶段Q可以羃短处理一个事务的旉Q以提高事务处理的效率。作Z阶段提交的一U特例,与两阶段一P一阶段提交也是标准的?/span></p> <p style="margin: 0cm 0cm 0pt;"><strong>XA的要?/strong> <br /> 对于jms来说Q需要配|支持XA?connection factory. <br /> 对于db来说Q需使用支持XA的JDBC driver. <br /> </p> <p style="margin: 0cm 0cm 0pt;"><strong>两阶D|?2 phase commit)</strong> <br /> 先说transaction的管理,如下图?nbsp;</p> <p style="margin: 0cm 0cm 0pt;"><img alt="" src="http://www.tkk7.com/images/blogjava_net/persister/046a643e-1b51-3aa3-9ac2-779f5e4755ea.bmp.png" width="447" height="237" /><br />   <br /> transaction manager与不同的resource manager都有交互? <br /> <br /> 在phase1Ӟtransaction manager向两个resouce询问是否可以准备提交。Resouce可回复ready, not_ready或是read_only. 当两个都readyӞ则可以进入phase2 q行提交。Q何一个回复not_ready则整个transaction 回滚。回复read_only的资源在phase2阶段被排除在提交q程之外? <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/persister/dd3536a3-d5fa-3e43-b905-8e13a755c9ca.bmp.png" width="300" height="256" /><br /> </p> <p style="margin: 0cm 0cm 0pt;"><br /> </p> <strong>2.JTA</strong><br /> JTA(Java Transaction API) ?J2EE q_提供了分布式事务服务?br /> 要用 JTA q行事务界定Q应用程序要调用 javax.transaction.UserTransaction 接口中的Ҏ? <p>让我们来x下面的话Q?br />  “?JTA 界定事务Q那么就需要有一个实?javax.sql.XADataSource ? javax.sql.XAConnection ?javax.sql.XAResource 接口?JDBC 驱动E序。一个实Cq些接口的驱动程序将可以参与 JTA 事务。一?XADataSource 对象是一?XAConnection 对象的工厂?XAConnection s 是参?JTA 事务?JDBC q接?#8221;<br /> 要用JTA事务Q必M用XADataSource来生数据库q接Q生的q接Z个XAq接?/p> <p>XAq接Qjavax.sql.XAConnectionQ和非XAQjava.sql.ConnectionQ连接的区别在于QXA可以参与JTA的事务,而且不支持自动提交?/p> Note:<br /> Oracle, Sybase, DB2, SQL Server,MySQL(5.0以后InnoDB存储引擎){大型数据库才支持XA, 支持分布事务?<br /> <br /> <strong>3.OFBiz中实现的事务<br /> </strong>OFBiz采用<a >Apache Commons DBCP</a>作ؓ数据库连接池技术,分布式事务是通过Apache <a >Geronimo Transaction</a>实现的。下面是部分实现cdp:<br /> <br /> <img alt="" src="http://www.tkk7.com/images/blogjava_net/persister/transaction.JPG" width="622" height="504" /><br /> <br /> <br /> <strong> </strong>TransactionFactory和ConnectionFactory都可以自己实现ƈ且在entityengine.xml中进行配|,OFBiz中默认配|的?/span></span>GeronimoTransactionFactory和DBCPConnectionFactory。OFBiz中实C务不需要显C用,在services.xml中的serviceq行配置Q配|的目有两个require-new-transaction和use-transactionQ是否v一个新的事务和是否启用事务Q默认是false和true。如果不是采用serviceQevent为java实现Q那么需要手动实C务,通常如下Q?br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000ff;">try</span><span style="color: #000000;"> {<br /> <br />      beganTransaction </span><span style="color: #000000;">=</span><span style="color: #000000;"> TransactionUtil.begin(DEFAULT_TX_TIMEOUT);<br /> <br /> </span><span style="color: #008000;">     //</span><span style="color: #008000;">db operation</span><span style="color: #008000;"><br /> </span><span style="color: #000000;">     return "success";<br /> } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {<br />      e.printStackTrace();<br />      TransactionUtil.rollback(beganTransaction, e.getMessage(), e);<br />      </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> </span><span style="color: #000000;">"</span><span style="color: #000000;">error</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br /> } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {<br />     TransactionUtil.commit(beganTransaction);<br /> }</span></div> <br /> <br /> <br /> <span style="font-size: 10pt;"><span style="font-size: 10pt;"><br /> </span></span> <img src ="http://www.tkk7.com/persister/aggbug/266439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/persister/" target="_blank">persister</a> 2009-04-19 18:01 <a href="http://www.tkk7.com/persister/archive/2009/04/19/266439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSWorkflow与OFBiz的集?/title><link>http://www.tkk7.com/persister/archive/2009/04/12/265066.html</link><dc:creator>persister</dc:creator><author>persister</author><pubDate>Sat, 11 Apr 2009 16:01:00 GMT</pubDate><guid>http://www.tkk7.com/persister/archive/2009/04/12/265066.html</guid><wfw:comment>http://www.tkk7.com/persister/comments/265066.html</wfw:comment><comments>http://www.tkk7.com/persister/archive/2009/04/12/265066.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/persister/comments/commentRss/265066.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/persister/services/trackbacks/265066.html</trackback:ping><description><![CDATA[     摘要: 1.OSWorklow的基本概? Osworkflow是完全用java语言~写的开放源代码的工作流引擎Q具有显著的灉|性及完全面向有技术背景的用户的特炏V用户可以根据自w的需求利用这Ƒּ源Y件设计简单或是复杂的工作。Osworkflow几乎提供了所有用户可能在实际程定义中需要用到的工作构成元素,如:环节QstepQ、条ӞconditionsQ、@环(loopsQ、分支(splitsQ?..  <a href='http://www.tkk7.com/persister/archive/2009/04/12/265066.html'>阅读全文</a><img src ="http://www.tkk7.com/persister/aggbug/265066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/persister/" target="_blank">persister</a> 2009-04-12 00:01 <a href="http://www.tkk7.com/persister/archive/2009/04/12/265066.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OFBiz's trunk version遇到的两个问?/title><link>http://www.tkk7.com/persister/archive/2009/03/30/262857.html</link><dc:creator>persister</dc:creator><author>persister</author><pubDate>Mon, 30 Mar 2009 04:38:00 GMT</pubDate><guid>http://www.tkk7.com/persister/archive/2009/03/30/262857.html</guid><wfw:comment>http://www.tkk7.com/persister/comments/262857.html</wfw:comment><comments>http://www.tkk7.com/persister/archive/2009/03/30/262857.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/persister/comments/commentRss/262857.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/persister/services/trackbacks/262857.html</trackback:ping><description><![CDATA[<h3 class="type_reprint" title="转蝲">1. <a >在eclipse下运行或调试Ofbiz的出?span class="hilite1">Can't</span> <span id="pftp99b" class="hilite2">find</span> <span id="7hdjdfx" class="hilite3">bundle</span> <span id="vthdpfn" class="hilite4">for</span> <span id="1jf7zb9" class="hilite5">base</span> </a></h3> <strong>关键? ofbiz</strong> <br /> <br /> eclipse 中利用org.ofbiz.<span id="d9b1dpb" class="hilite5">base</span>.start.Startc运行Ofbiz 出现错误: <br /> <br /> Exception in thread "main" java.lang.ExceptionInInitializerError <br /> at org.ofbiz.<span id="z19l99x" class="hilite5">base</span>.util.Debug.<clinit>(Debug.java:90) <br /> at org.ofbiz.<span id="v77999p" class="hilite5">base</span>.container.ContainerLoader.load(ContainerLoader.java:50) <br /> at org.ofbiz.<span id="bh9dlf7" class="hilite5">base</span>.start.Start.initStartLoaders(Start.java:248) <br /> at org.ofbiz.<span id="j7r9v9r" class="hilite5">base</span>.start.Start.init(Start.java:87) <br /> at org.ofbiz.<span id="hnb79dp" class="hilite5">base</span>.start.Start.main(Start.java:403) <br /> Caused by: java.util.MissingResourceException: <span id="rfd197l" class="hilite1">Can't</span> <span id="7vb9b9r" class="hilite2">find</span> <span id="7xt99b9" class="hilite3">bundle</span> <span id="v7rf79v" class="hilite4">for</span> <span id="fzn17p9" class="hilite5">base</span> <span id="thtj9hb" class="hilite6">name</span> <span id="7rjvljn" class="hilite7">cache</span>, <span id="zjd9tv9" class="hilite8">locale</span> zh_CN <br /> at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:836) <br /> at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:805) <br /> at java.util.ResourceBundle.getBundle(ResourceBundle.java:549) <br /> at org.ofbiz.<span id="7vfjv9x" class="hilite5">base</span>.util.<span id="ld7bv9f" class="hilite7">cache</span>.UtilCache.setPropertiesParams(UtilCache.java:217) <br /> at org.ofbiz.<span id="x99jf97" class="hilite5">base</span>.util.<span id="tfhd99x" class="hilite7">cache</span>.UtilCache.setPropertiesParams(UtilCache.java:213) <br /> at org.ofbiz.<span id="7r9d9z9" class="hilite5">base</span>.util.<span id="rjpjfjn" class="hilite7">cache</span>.UtilCache.<init>(UtilCache.java:172) <br /> at org.ofbiz.<span id="d79h7jn" class="hilite5">base</span>.util.UtilProperties.<clinit>(UtilProperties.java:53) <br /> ... 5 more <br /> <br /> 原因是没有正设|Debug环境QOFBiz Wiki上的<a >文章</a>描述的很详细Q按照它的步骤设|,׃会出C面的问题?br /> <br /> 2.trunk 中定义entity时在entitymodel中,如果定义的group在org.ofbiz中就不需要在entitygroup中定义,而自定义?br /> 如在com.aicent中,实体存放在不同的数据库,那么需要定义entitygroup。因此导致的一个问题就是:<br /> 如果有自定义实体在entitymodel中定义了但是没有加入到entitygroup中,那么׃D此实体默认放在在org.ofbiz中从而在ofbiz的数据库中徏表了Q这点得注意?br /> <br /> <img src ="http://www.tkk7.com/persister/aggbug/262857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/persister/" target="_blank">persister</a> 2009-03-30 12:38 <a href="http://www.tkk7.com/persister/archive/2009/03/30/262857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OFBiz开发需要用到的几个重要Q配|)文ghttp://www.tkk7.com/persister/archive/2009/01/21/252211.htmlpersisterpersisterWed, 21 Jan 2009 06:25:00 GMThttp://www.tkk7.com/persister/archive/2009/01/21/252211.htmlhttp://www.tkk7.com/persister/comments/252211.htmlhttp://www.tkk7.com/persister/archive/2009/01/21/252211.html#Feedback0http://www.tkk7.com/persister/comments/commentRss/252211.htmlhttp://www.tkk7.com/persister/services/trackbacks/252211.html
1、首先是entityengine.xml文gQ这个文件是配置数据源的Q也包括数据库连接池、事务实现类的配|和字段cd配置文g。企业pȝ的开发一般都M开数据库,那么在OFBiz中,数据库的配置在q个配置文g里面Q先配置一个group-mapQ然后配|其对应的数据源Q?br />
<delegator name="default" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main"
   distributed-cache-clear-enabled
="false">
        
<group-map group-name="org.ofbiz" datasource-name="ofbiz"/>
        
<group-map group-name="com.aicent" datasource-name="portal"/>
    
</delegator>

    
<datasource name="ofbiz"
            helper-class
="org.ofbiz.entity.datasource.GenericHelperDAO"
            field-type-name
="mysql"
            check-on-start
="false"
            add-missing-on-start
="false"
            check-pks-on-start
="false"
            use-foreign-keys
="true"
            join-style
="ansi-no-parenthesis"
            alias-view-columns
="false"
            drop-fk-use-foreign-key-keyword
="true"
            table-type
="InnoDB" 
            character-set
="latin1"
            collate
="latin1_swedish_ci">
        
<read-data reader-name="seed"/>
        
<read-data reader-name="seed-initial"/>
        
<read-data reader-name="demo"/>
        
<read-data reader-name="ext"/>
        
<inline-jdbc
                
jdbc-driver="com.mysql.jdbc.Driver"
        jdbc-uri
="jdbc:mysql://localhost/ofbiztrunk"
                jdbc-username
="root"
                jdbc-password
="123456"
                isolation-level
="ReadCommitted"
                pool-minsize
="2"
                pool-maxsize
="20"/>
        
<!-- <jndi-jdbc jndi-server-name="localjndi" jndi-name="java:/MySqlDataSource" isolation-level="Serializable"/> -->
    
</datasource>

datasource配置里面有一?span style="color: #ff0000;">field-type-name="mysql"Q到entitymodel.xml配置文gq道是q吗用的了?br />
2.entitymodel.xml & entitygroup.xml
  OFBiz本质上来说还是面向数据库的设计,entitymodel.xml的配|entity的,entity实体对应数据库里面的tableQ实体的field对应数据库里面的字段,如下是一个entity配置Q?br />
<entity entity-name="Customerinfo" package-name="com.aicent.ccb" no-auto-stamp="true"
        title
="customerinfo">
        
<field name="id" type="int10" ></field>
        
<field name="name" type="varchar128"></field>
        
<field name="customernameshort" type="varchar16"></field>
        
<field name="country" type="varchar64"></field>
        
<field name="businessaddr" type="text"></field>
        
<field name="mailaddr" type="text"></field>
        
<field name="billaddr" type="text"></field>
        
<field name="phone" type="varchar32"></field>
        
<field name="fax" type="varchar32"></field>
        
<field name="website" type="varchar128"></field>
        
<field name="note" type="text"></field>
</entity>

里面有一个typeQ这个type对应数据库字D늚cdQ日期型Q字W串型,整型{)Q这个对于关pd哪里呢?在刚才说的field-type-name里面配置Q如果配|ؓmysqlQ那么entitygengine.xml中mysql?br /> field-type指向的文件是Q?br />
<field-type name="mysql" loader="fieldfile" location="fieldtypemysql.xml"/>

在fieldtypemysql.xml中,可以找到如int10,varchar128表示的实际mysql字段cd了:

 1 <fieldtypemodel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 2         xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/fieldtypemodel.xsd">
 3   <!-- ===================== field-type-def ==================== -->
 4     <!-- General Types --> 
 5     <field-type-def type="blob" sql-type="BLOB" java-type="java.sql.Blob"></field-type-def>
 6     
 7     <field-type-def type="date-time" sql-type="DATETIME" java-type="java.sql.Timestamp"></field-type-def>
 8     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>
 9     <field-type-def type="time" sql-type="TIME" java-type="java.sql.Time"></field-type-def>
10     
11     <field-type-def type="currency-amount" sql-type="DECIMAL(18,2)" java-type="java.math.BigDecimal"><validate method="isSignedDouble" /></field-type-def>
12     <field-type-def type="currency-precise" sql-type="DECIMAL(18,3)" java-type="java.math.BigDecimal"><validate method="isSignedDouble" /></field-type-def>
13     <field-type-def type="fixed-point" sql-type="DECIMAL(18,6)" java-type="java.math.BigDecimal"><validate method="isSignedDouble" /></field-type-def>
14     <field-type-def type="floating-point" sql-type="DECIMAL(18,6)" java-type="Double"><validate method="isSignedDouble" /></field-type-def>
15     <field-type-def type="numeric" sql-type="DECIMAL(20,0)" java-type="Long"><validate method="isSignedLong" /></field-type-def>
16     <field-type-def type="integer" sql-type="INTEGER" java-type="Integer"></field-type-def>
17     
18     <field-type-def type="id" sql-type="VARCHAR(20)" java-type="String"></field-type-def>
19     <field-type-def type="id-long" sql-type="VARCHAR(60)" java-type="String"></field-type-def>
20     <field-type-def type="id-vlong" sql-type="VARCHAR(250)" java-type="String"></field-type-def>
21     
22     <field-type-def type="indicator" sql-type="CHAR(1)" java-type="String"></field-type-def>
23     <field-type-def type="very-short" sql-type="VARCHAR(10)" java-type="String"></field-type-def>
24     <field-type-def type="short-varchar" sql-type="VARCHAR(60)" java-type="String"></field-type-def>
25     <field-type-def type="long-varchar" sql-type="VARCHAR(255)" java-type="String"></field-type-def>
26     <field-type-def type="very-long" sql-type="LONGTEXT" java-type="String"></field-type-def>
27    
28     <field-type-def type="comment" sql-type="VARCHAR(255)" java-type="String"></field-type-def>
29     <field-type-def type="description" sql-type="VARCHAR(255)" java-type="String"></field-type-def>
30     <field-type-def type="name" sql-type="VARCHAR(100)" java-type="String"></field-type-def>
31     <field-type-def type="value" sql-type="VARCHAR(255)" java-type="String"></field-type-def>
32     
33     <!-- customize field type definitions for ccb -->
34     <field-type-def type="text" sql-type="TEXT" java-type="String"></field-type-def>
35     
36     <field-type-def type="char" sql-type="CHAR(1)" java-type="String"></field-type-def>
37     <field-type-def type="char125" sql-type="CHAR(125)" java-type="String"></field-type-def>
38     <field-type-def type="varchar16" sql-type="VARCHAR(16)" java-type="String"></field-type-def>
39     <field-type-def type="varchar20" sql-type="VARCHAR(20)" java-type="String"></field-type-def>
40     <field-type-def type="varchar24" sql-type="VARCHAR(24)" java-type="String"></field-type-def>
41     <field-type-def type="varchar50" sql-type="VARCHAR(50)" java-type="String"></field-type-def>
42     <field-type-def type="varchar64" sql-type="VARCHAR(64)" java-type="String"></field-type-def>
43     <field-type-def type="varchar128" sql-type="VARCHAR(128)" java-type="String"></field-type-def>
44 </fieldtypemodel>

OFBizq里Z么不在entitymodel里面直接使用字段在数据库中的cdQ而这么绕呢?我想臛_有两个目的:首先是公怼业开发时可以针对使用的字D늱型有一个规范,所有的字段都采用这个配|文件中的字D늱型,而不是开发h员自己随意定义数据库字段的类型;W二是ؓ了用不同Vendor的数据库Q如果想从mysql换成oracleQ只需要定义另一份fieldtypeoracle.xmlQfield-type-def中sql-type不变Q而sql-tye换成oracle的类型即可?br />
entitygroup.xml配置文g时用于配|entitymodel.xml中配|的entity是属于哪个group的,q个group对应entityengine.xml中的group-nameQ如果忘记在entitygroup.xml中配|,那么在OFBiz 9之前Q这个entity无法用,不会创徏相应的tableQOFBiz 9以后Q默认的group name是org.ofbiz?br />
<entitygroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation
="http://www.ofbiz.org/dtds/entitygroup.xsd">


    
<entity-group group="com.aicent" entity="Customerextra" />
    
<entity-group group="com.aicent" entity="Customerinfo" />

</entitygroup>

3.ofbiz-containers.xml 里面配置了各U容器类Q经怿改的容器是name为catalina-container的容器,使用的是embeded tomcatQ里面可以修改各Utomcat的配|项Q就像我们修改tomcat的配|文件server.xml一P在里面修改端口等信息?br />
4.log4j.xml 日志配置文g

5.component-load.xml q个文g在几个文件夹中都存在Q如framework,applications,specialpurpose中。OFBiz一个个应用实现为componentQ这些componnet是就好像tomcat中webapps中的一个个web应用。每ơ是否加载这个component可以在component-load.xml配置Q如果不惛_载,注释掉就可以?br />
<component-loader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation
="http://ofbiz.apache.org/dtds/component-loader.xsd">
    
<load-component component-location="commonext"/><!-- common component used by most other components -->     
    
<load-component component-location="securityext"/>
    
<!--
    <load-component component-location="party"/>
    <load-component component-location="content"/>
    <load-component component-location="workeffort"/>
    <load-component component-location="product"/>
    <load-component component-location="manufacturing"/>
    <load-component component-location="accounting"/>
    <load-component component-location="humanres"/>
    <load-component component-location="order"/>
    <load-component component-location="marketing"/>
    
-->
</component-loader>

到底哪些目录下的component-load.xml有效呢,q个目录在framework/base/config/component-load.xmlq进行配|:

<component-loader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation
="http://ofbiz.apache.org/dtds/component-loader.xsd">
    
<load-components parent-directory="framework"/> 
    
<load-components parent-directory="themes"/> 
    
<load-components parent-directory="applications"/>
    
<load-components parent-directory="specialpurpose"/>
    
<load-components parent-directory="hot-deploy"/>
</component-loader>

6.general.properties q里面配|的东西很多Q大家自己去看吧?br />
7.cache.properties 配置OFBiz中的~存Q配|这个文仉要对OFBiz中的~存有所了解Q这个在后箋文章中进行分析?br />
其他q有一些比较配|的文gQ就不一一说明了?br />


persister 2009-01-21 14:25 发表评论
]]>
վ֩ģ壺 ޾Ʒպav| ԺѵȫƵ| ް鵺̳| ĸԴѹۿ| йëƬѹۿƵ| ޹Ʒþҹ| ޾ƷƵ| ŮվѸƵ| ѿƬ| պһ| ۺɫ¶| žžžƷƵ| þþþþëƬѿ| ޾ƷVĻ| ŷպۺ߶| һëƬշ| ˾Ƶ| Ӱ߹ۿѸ| С˵ɫͼ| ۲ӰԺ߹ۿ| ޾ƷۺϾþ| ѵվ߹ۿ| Ʒ99Ʒþ| ĻAVһ| һƷƵ| պѿ| avëƬһ| 99þþþþѿ| Ӱ| ޾ƷҾþþþþ| ҹƵ| ĻƵһ| Ʒһ| ߹ۿ˳վ| ߹ۿƷ| պƷ| ҹ߹ۿ| ĻƷַ| ѹëƬ| պþۺĻ| ޿һ|