ofbiz中运行配置及流程
经过一段时间的学习,了解ofbiz的运行流程,在这个框架中,前端页面使用的是ftl文件,所有的页面都要通过模板进行渲染之后才会展示出来,页面知识不做过多的介绍,在这个框架中其核心在于control控制器,即每个组件中的WEB_INF/controller.xml,在这里面实现页面的跳转走向,由此特对controller.xml 、service.xml、Screen.xml三个配置文件中各找一份代码进行分析:
Controller.xml:
<request-map uri="createaddress"> <description>新建地址</description> <security https="false" auth="true"/> <event type="service" invoke="createaddress" path="component://baseSupplyChain/servicedef/services.xml" /> <response name="success" type="request-redirect" value="addressManage"/> </request-map> <view-map name="addressManage" type="screen" page="component://baseSupplyChain/widget/baseSupplyChainScreens.xml#addressManage"/>
在这里我只取其中完整的一个控制流程给大家介绍,相信通过标签大家也能够看明白,第一行<request-map>负责接收请求,第二行<description>是进行描述,在实际代码执行中不执行,只是方便开发人员理解,第三行<security>表示设置提交的规则,第四行<event>则是负责跳转到对应的java执行代码进行逻辑处理,invoke=“”是对应后面路径中的方法,在这里invoke可以是service也可以是java类中的方法,建议使用service,扩展更方便,后面具体介绍service中的配置,第五行<response>则是负责跳转到相应页面(screen),如果负责跳转页面则type=“request-redirect” value=“”则是跳转到对应的screen,如果是json进行一部提交,则value=“json”,type=“request”,若只是调到拿一个页面,设置type=“view” 后面value=“”设置相应的screen就可以了,如果当页面进行请求到“addressManage”时候,就会通过这段代码进行控制,最后一行代码则是负责跳转到相应的sereen中的addressManage;
Screen.xml:
<screen name="addressManage"> <section> <actions> <set field="headerItem" value="addressManage"/> <set field="landMark" from-field="parameters.landMark"/> <set field="address" from-field="parameters.address"/> <entity-condition list="LbaseAddressList" entity-name="LbaseAddress"> <condition-list> <condition-expr field-name="landMark" from-field="landMark" operator="like" value="%${parameters.landMark}%" ignore-if-null="true" ignore-if-empty="true"/> <condition-expr field-name="address" from-field="address" operator="like" value="%${parameters.address}%" ignore-if-null="true" ignore-if-empty="true"/> </condition-list> </entity-condition> <entity-and list="LbaseWarehouseManageList" entity-name="LbaseWarehouseManage"></entity-and><!--仓库 --> </actions> <widgets> <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}"> <decorator-section name="body"> <platform-specific> <html> <html-template location="component://baseSupplyChain/webapp/baseSupplyChain/baseSupply/addressManageList.ftl"/> </html> </platform-specific> </decorator-section> </decorator-screen> </widgets> </section> </screen>
在这里不多说,进行模板渲染中location是指渲染哪一个ftl文件,<set>则是负责数据的传递给value,然后页面中通过field中的名字就可以获取,<entity-condition> 中则可以实现直接从数据库中实体类名字就可以取到表数据,当然<condition-exper>则是指查询条件,<entity-one>则是根据条件查询一条数据, <decorator-screen>和<decorator-section name="body">则需要注意,如果是弹出框什么的(类似编辑框),就需要将此标签去掉;
Service.xml:
<service name="createaddress" engine="java" invoke="createaddress" location="ofbiz.supply.service.AddressServices"> <description>新增地址</description> <attribute name="landMark" mode="IN" type="String"/> <attribute name="address" mode="IN" type="String"/> <attribute name="warehouseId" mode="IN" type="String" optional="true" /> <attribute name="whether" mode="IN" type="String"/> </service>
这就是之前在controller.xml中event所要跳转的地方,invoke对应后面location路径中类的方法,(此处也可以是xml中配置的simple方法,但是用的比较少,在此不做介绍),后面的<attributes>则是需要从从页面传到后台的参数,其传递方向通过mode=“”中的in或者out进行控制,如果参数存在着不传递情况,需要添加 optional="true"进行修饰,否则就会报错,当然controller.xml中跳转的java方法和通过service跳转的java方法写法不一样,接收参数方式一不一样,,直接跳转的java类则需要借助定义的request和response,而通过service的则是通过delegator,细节不再说明,贴代码对比一下吧:
通过service跳转的java方法:
public static Map<String, Object> createaddress(DispatchContext ctx, Map<String, ? extends Object> context) throws Exception{ Delegator delegator = ctx.getDelegator(); //定义map Map<String, Object> result = FastMap.newInstance(); GenericValue sendCarIn = delegator.makeValue("LbaseAddress"); String addressId =delegator.getNextSeqId("LbaseAddress").toString(); //获取数据 sendCarIn.set("addressId",Long.parseLong(addressId)); //主键 sendCarIn.set("landMark",(String)context.get("landMark")); //起始地址 sendCarIn.set("address",(String)context.get("address")); //目的地址 sendCarIn.set("warehouseId",(String)context.get("warehouseId")); //仓库 sendCarIn.set("whether",(String)context.get("whether")); // 是否是仓库 delegator.create("LbaseAddress",sendCarIn); return result; }
并且注意,如果没有在service中设置out传出的map,在java中就不能够返回一个有数据的map,报错,
直接跳转的java方法:
public static String createContCode(HttpServletRequest request,HttpServletResponse response)throws Exception{ Delegator delegator = (Delegator) request.getAttribute("delegator"); Map<String, Object> context = FastMap.newInstance(); String id = delegator.getNextSeqId("LbaseContCode").toString(); //获取数据 context.put("id", Long.parseLong(id)); context.put("bccContSize", request.getParameter("bccContSize")); context.put("bccContType", request.getParameter("bccContType")); context.put("bccContWt", request.getParameter("bccContWt")); context.put("bccContChi", request.getParameter("bccContChi")); context.put("bccCode95", request.getParameter("bccCode95")); context.put("bccCodeHj", request.getParameter("bccCodeHj")); context.put("bccCodeOocl", request.getParameter("bccCodeOocl")); context.put("bccTeu", request.getParameter("bccTeu")); context.put("bccFeu", request.getParameter("bccFeu")); delegator.create("LbaseContCode",context); return "success"; }
这两种方式自己接触之后可慢慢进行比较,(当然如果是json一部提交处理请求,则在java面jangle数据以json格式传到前端)这样整个流程就可以执行下来了。