最近接到一个预约管理系项目,准备用ofbiz实战一下。不多说,首先创建一个项目吧。
1. 首先创建相关文件夹。
具体创建步骤就不详细说了,建好后的文件夹结构如下图:
2. hot-deploy\booking目录下创建ofbiz-component.xml文件
<ofbiz-component name="booking" enabled="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd">
<!-- define resource loaders; most common is to use the component resource loader -->
<resource-loader name="main" type="component"/>
<!-- place the config directory on the classpath to access configuration files -->
<classpath type="dir" location="config"/>
<entity-resource type="data" reader-name="seed" loader="main" location="data/BookingDemoData.xml"/>
<!-- web applications; will be mounted when using the embedded container -->
<webapp name="booking"
title="Booking"
menu-name="secondary"
server="default-server"
location="webapp/booking"
base-permission="OFBTOOLS,BOOKING"
mount-point="/booking"/>
</ofbiz-component>
3. hot-deploy\booking\config目录下创建下面几个文件.
BookingUiLabels.xml
<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd">
<!--
<property key="ContentFopFonts">
<value xml:lang="en">FOP fonts in a PDF</value>
<value xml:lang="zh">PDF中的FOP字体</value>
</property>
-->
</resource>
BookingHelpUiLabels.xml
<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd">
</resource>
<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd">
</resource>
bookingpdf.properties默认没用到可以为空
# If Y, the default.pdf.owner.password will be used as owner password, the user input password will be used as user password;
# if N, the user input password will be used as owner password and user password.
#use.default.pdf.owner.password=N
#default.pdf.owner.password=ofbiz
4. hot-deploy\booking\webapp\booking\WEB-INF目录下创建controller.xml和web.xml
controller.xml
<?xml version="1.0" encoding="UTF-8"?>
<site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://ofbiz.apache.org/Site-Conf" xsi:schemaLocation="http://ofbiz.apache.org/Site-Conf http://ofbiz.apache.org/dtds/site-conf.xsd">
<include location="component://common/webcommon/WEB-INF/common-controller.xml"/>
<include location="component://common/webcommon/WEB-INF/portal-controller.xml"/>
<description>Example Component Site Configuration File</description>
<!-- Request Mappings -->
<request-map uri="main"><security https="true" auth="true"/><response name="success" type="view" value="main"/></request-map>
<!-- View Mappings -->
<view-map name="main" type="screen" page="component://booking/widget/booking/BookingScreens.xml#main"/>
</site-conf>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0">
<display-name>Apache OFBiz - Example Application</display-name>
<description>Example Application of the Apache OFBiz Project</description>
<context-param>
<description>A unique name used to identify/recognize the local dispatcher for the Service Engine</description>
<param-name>localDispatcherName</param-name><param-value>booking</param-value>
</context-param>
<context-param>
<description>The Name of the Entity Delegator to use, defined in entityengine.xml</description>
<param-name>entityDelegatorName</param-name><param-value>default</param-value>
</context-param>
<context-param>
<description>The location of the main-decorator screen to use for this webapp; referred to as a context variable in screen def XML files.</description>
<param-name>mainDecoratorLocation</param-name>
<param-value>component://booking/widget/booking/CommonScreens.xml</param-value>
</context-param>
<context-param>
<description>Remove unnecessary whitespace from HTML output.</description>
<param-name>compressHTML</param-name>
<param-value>false</param-value>
</context-param>
<filter>
<display-name>ControlFilter</display-name>
<filter-name>ControlFilter</filter-name>
<filter-class>org.apache.ofbiz.webapp.control.ControlFilter</filter-class>
<init-param>
<param-name>allowedPaths</param-name>
<param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/js:/ws</param-value>
</init-param>
<init-param>
<param-name>redirectPath</param-name>
<param-value>/control/main</param-value>
</init-param>
</filter>
<filter>
<display-name>ContextFilter</display-name>
<filter-name>ContextFilter</filter-name>
<filter-class>org.apache.ofbiz.webapp.control.ContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ControlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener><listener-class>org.apache.ofbiz.webapp.control.ControlEventListener</listener-class></listener>
<listener><listener-class>org.apache.ofbiz.webapp.control.LoginEventListener</listener-class></listener>
<!-- NOTE: not all app servers support mounting implementations of the HttpSessionActivationListener interface -->
<!-- <listener><listener-class>org.apache.ofbiz.webapp.control.ControlActivationEventListener</listener-class></listener> -->
<servlet>
<description>Main Control Servlet</description>
<display-name>ControlServlet</display-name>
<servlet-name>ControlServlet</servlet-name>
<servlet-class>org.apache.ofbiz.webapp.control.ControlServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>ControlServlet</servlet-name><url-pattern>/control/*</url-pattern></servlet-mapping>
<session-config>
<session-timeout>60</session-timeout><!-- in minutes -->
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
</web-app>
注意:web.xml文件需要修改2个地方,localDispatcherName和mainDecoratorLocation参数需要修改为对应的组件名称。
<%@ page import="org.apache.ofbiz.base.util.*" %>
<html>
<head>
<title>OFBiz Message</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<% String errorMsg = (String) request.getAttribute("_ERROR_MESSAGE_"); %>
<body bgcolor="#FFFFFF">
<div align="center">
<br/>
<table width="100%" border="1" height="200">
<tr>
<td>
<table width="100%" border="0" height="200">
<tr bgcolor="#CC6666">
<td height="45">
<div align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="4" color="#FFFFFF"><b>:ERROR MESSAGE:</b></font></div>
</td>
</tr>
<tr>
<td>
<div align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><%=UtilFormatOut.replaceString(errorMsg, "\n", "<br/>")%></font></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div align="center"></div>
</body>
</html>
5. hot-deploy\booking\widget\booking目录下创建三个文件
CommonScreens.xml<?xml version="1.0" encoding="UTF-8"?>
<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://ofbiz.apache.org/Widget-Screen" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen http://ofbiz.apache.org/dtds/widget-screen.xsd">
<screen name="main-decorator">
<section>
<actions>
<!-- base/top/specific map first, then more common map added for shared labels -->
<property-map resource="BookingUiLabels" map-name="uiLabelMap" global="true"/>
<property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/>
<set field="layoutSettings.companyName" from-field="uiLabelMap.BookingCompanyName" global="true"/>
<set field="layoutSettings.companySubtitle" from-field="uiLabelMap.BookingCompanySubtitle" global="true"/>
<set field="activeApp" value="booking" global="true"/>
<set field="applicationMenuName" value="BookingAppBar" global="true"/>
<set field="applicationMenuLocation" value="component://booking/widget/booking/BookingMenus.xml" global="true"/>
<set field="applicationTitle" value="${uiLabelMap.BookingApplication}" global="true"/>
</actions>
<widgets>
<section>
<condition>
<if-has-permission permission="BOOKING" action="_VIEW"/>
</condition>
<actions>
<!-- <set field="layoutSettings.javaScripts[]" value="/example/js/ExamplePushNotifications.js" global="true"/>-->
</actions>
</section>
<include-screen name="ApplicationDecorator" location="component://commonext/widget/CommonScreens.xml"/>
</widgets>
</section>
</screen>
</screens>
BookingScreens.xml
<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://ofbiz.apache.org/Widget-Screen" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen http://ofbiz.apache.org/dtds/widget-screen.xsd">
<screen name="main">
<section>
<actions>
<set field="tabButtonItem" value="main"/>
</actions>
<widgets>
<decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<label>hello world</label>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
</screens>
BookingMenus.xml
xmlns="http://ofbiz.apache.org/Widget-Menu" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Menu http://ofbiz.apache.org/dtds/widget-menu.xsd">
<menu name="BookingAppBar" title="${uiLabelMap.ExampleApplication}" extends="CommonAppBarMenu" extends-resource="component://common/widget/CommonMenus.xml">
<!--
<menu-item name="ExampleMenuItem" title="${uiLabelMap.ExampleExample}">
<link target="FindExample"/>
</menu-item>
-->
</menu>
</menus>
注意menu的name必须存在一个和 CommonScreens.xml文件中配置的applicationMenuName参数值一致,否则会报错。
OK,现在项目基本创建好了,接下来需要配置写demo数据,创建用户以及配置相应的权限,然后开始访问新的项目。
6. 创建用户并配置权限
创建文件hot-deploy\booking\data\BookingDemoUser.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-engine-xml>
<!--首先创建相应的权限-->
<SecurityPermission description="预约系统查询权限." permissionId="BOOKING_VIEW"/>
<SecurityPermission description="预约系统创建权限." permissionId="BOOKING_CREATE"/>
<SecurityPermission description="预约系统更新权限." permissionId="BOOKING_UPDATE"/>
<SecurityPermission description="预约系统删除权限." permissionId="BOOKING_DELETE"/>
<SecurityPermission description="预约系统管理员拥有所有权限." permissionId="BOOKING_ADMIN"/>
<!--然后创建相应的安全组-->
<SecurityGroup groupId="bookingAdmin" description="预约系统管理员权限组!"/>
<!--接着安全组与权限关联-->
<SecurityGroupPermission groupId="bookingAdmin" permissionId="BOOKING_ADMIN"/>
<SecurityGroupPermission groupId="bookingAdmin" permissionId="OFBTOOLS_VIEW"/>
<!--为了超级用户admin也能访问预约系统,所以需要把权限加入到FULLADMIN安全组-->
<SecurityGroupPermission groupId="FULLADMIN" permissionId="BOOKING_ADMIN"/>
<!--接着创建预约系统管理员账号-->
<UserLogin userLoginId="booking" currentPassword="{SHA}47b56994cbc2b6d10aa1be30f70165adb305a41a" passwordHint="" partyId="booking"/>
<!--最后把预约系统管理员账号管理对应的安全组-->
<UserLoginSecurityGroup groupId="bookingAdmin" userLoginId="booking" fromDate="2017-01-01 00:00:00"/>
</entity-engine-xml>
这个文件因为在ofbiz-component.xml中有配置,所以项目启动时会自动加载。
测试运行发现报下面错误:
:ERROR MESSAGE:
|
org.apache.ofbiz.widget.renderer.ScreenRenderException: Error rendering screen [component://common/widget/CommonScreens.xml#login]: org.apache.ofbiz.widget.renderer.ScreenRenderException: Error rendering screen [component://booking/widget/booking/CommonScreens.xml#main-decorator]: java.lang.IllegalArgumentException: Could not find resource bundle [BookingUiLabels] in the locale [zh_CN] (Could not find resource bundle [BookingUiLabels] in the locale [zh_CN]) (Error rendering screen [component://booking/widget/booking/CommonScreens.xml#main-decorator]: java.lang.IllegalArgumentException: Could not find resource bundle [BookingUiLabels] in the locale [zh_CN] (Could not find resource bundle [BookingUiLabels] in the locale [zh_CN]))
|
解决方案:取消BookingUiLabels.xml里的注释,resource标签里至少包含一个property的定义。
使用BookingDemoUser.xml中定义的用户以及admin用户都无法登录系统。检测后发现BookingDemoUser.xml里的数据并没有导入到数据库中。
解决方案有2种:
运行命令gradlew loadDefault
或者
用admin登录webtools系统,然后使用实体引擎导入数据。
这里我用的的第二种比较快速,并且不影响其他数据。
如上图,把BookingDemoUser.xml里的内容复制进去,然后点击【导入文本】按钮提交。
结果发现报错了。把UserLogin实体记录导入的partyId属性去掉,因为这个有外键关联会导致报错。所以先去掉吧。然后点击【导入文本】按钮提交就好了。
最后访问https://10.100.1.240:8443/booking,使用booking/ofbiz登录显示如下界面:
配置好国际化文件CommonUiLabels.xml,BookingUiLabels.xml,以及对应的菜单文件BookingMenus.xml。一个系统主要的框架就搭建好了。具体配置之后章节在详细介绍。