ofbiz项目开发主要代码模块:
1.配置controller.xml。(具体路径:hot-deploy\booking\webapp\booking\WEB-INF目录下)
只有配置了controller.xml才能对用户的请求进行映射处理。
2.配置XXXScreens.xml与XXXForms.xml。(所在目录:hot-deploy\booking\widget\booking)
配置上面2个文件可以实现界面的控件以及布局。如果有些地方不好布局,可以使freemarker模板技术,通过ftl文件布局。
3.配置service和entity。
这个主要配置services.xml,secas.xml,eecas.xml。通过配置上面文件实现控制后台业务逻辑处理流程。
4.业务逻辑实现。
编写脚本,或者java类实现业务逻辑。
第1,3点内容我都放如 ofbiz实战——实验室预约系统共用配置文件 中了,具体可以参考里面的配置。下面主要贴一下第2和4点的配置以及实现。
配置StudentScreens.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="FindStudent">
<section>
<actions>
<set field="titleProperty" value="StuInfoManange"/>
<set field="headerItem" value="StuInfoManange"/>
<set field="viewIndex" from-field="parameters.VIEW_INDEX" type="Integer"/>
<property-to-field resource="widget" property="widget.form.defaultViewSize" field="viewSizeDefaultValue"/>
<set field="viewSize" from-field="parameters.VIEW_SIZE" type="Integer" default-value="${viewSizeDefaultValue}"/>
</actions>
<widgets>
<decorator-screen name="CommonBookingDecorator" location="component://booking/widget/booking/CommonScreens.xml">
<decorator-section name="body">
<section>
<widgets>
<decorator-screen name="FindScreenDecorator" location="component://common/widget/CommonScreens.xml">
<decorator-section name="menu-bar">
<container style="button-bar">
<link target="EditStudent" text="${uiLabelMap.EditStudent}" style="buttontext"/>
<link target="ImportStudentsPage" text="${uiLabelMap.ImportStudents}" style="buttontext"/>
<!--
<platform-specific>
<html><html-template location="component://booking/template/booking/StudentButtonBar.ftl"/></html>
</platform-specific>
-->
</container>
</decorator-section>
<decorator-section name="search-options">
<include-form name="FindStudent" location="component://booking/widget/booking/StudentForms.xml"/>
</decorator-section>
<decorator-section name="search-results">
<include-form name="ListFindStudent" location="component://booking/widget/booking/StudentForms.xml"/>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
<screen name="EditStudent">
<section>
<actions>
<set field="titleProperty" value="StuInfoManange"/>
<set field="headerItem" value="StuInfoManange"/>
<entity-one entity-name="Student" value-field="student"/>
</actions>
<widgets>
<decorator-screen name="CommonBookingDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<container style="button-bar">
<link target="FindStudent" text="${uiLabelMap.CommonBack}" style="buttontext"/>
</container>
<screenlet title="${groovy: parameters.stuId ? uiLabelMap.CommonEdit : uiLabelMap.CommonAdd}">
<include-form name="EditStudent" location="component://booking/widget/booking/StudentForms.xml"/>
</screenlet>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
<screen name="LookupStudent">
<section>
<actions>
<property-map resource="BookingUiLabels" map-name="uiLabelMap" global="true"/>
<set field="title" value="${uiLabelMap.PageTitleLookupStudent}"/>
<set field="queryString" from-field="result.queryString"/>
<set field="entityName" value="Student"/>
<set field="searchFields" value="[stuId, name, stuNumber]"/>
</actions>
<widgets>
<decorator-screen name="LookupDecorator" location="component://common/widget/CommonScreens.xml">
<decorator-section name="search-options">
<include-form name="LookupStudent" location="component://booking/widget/booking/StudentForms.xml"/>
</decorator-section>
<decorator-section name="search-results">
<include-form name="ListLookupStudent" location="component://booking/widget/booking/StudentForms.xml"/>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
<screen name="ImportStudentsPage">
<section>
<actions>
<set field="titleProperty" value="StuInfoManange"/>
<set field="headerItem" value="StuInfoManange"/>
</actions>
<widgets>
<decorator-screen name="CommonBookingDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<container style="button-bar">
<link target="FindStudent" text="${uiLabelMap.CommonBack}" style="buttontext"/>
<link target="downloadTemplet" text="${uiLabelMap.BookingDownloadStudentTemplet}" style="buttontext"/>
</container>
<screenlet title="${uiLabelMap.ImportStudents}">
<include-form name="ImportStudentsPage" location="component://booking/widget/booking/StudentForms.xml"/>
</screenlet>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
</screens>
配置StudentForms.xml
<?xml version="1.0" encoding="UTF-8"?>
<forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://ofbiz.apache.org/Widget-Form" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Form http://ofbiz.apache.org/dtds/widget-form.xsd">
<form name="FindStudent" target="FindStudent" title="" type="single"
header-row-style="header-row" default-table-style="basic-table">
<field name="name" title="${uiLabelMap.BookingName}"><text-find/></field>
<field name="stuNumber" title="${uiLabelMap.BookingStudentStuNumber}"><text-find/></field>
<field name="class" title="${uiLabelMap.BookingStudentClass}"><text-find/></field>
<field name="sex" title="${uiLabelMap.BookingSex}">
<drop-down allow-empty="true" >
<option key="Male" description="${uiLabelMap.CommonMale}"/>
<option key="Female" description="${uiLabelMap.CommonFemale}"/>
</drop-down>
</field>
<field name="submitButton" title="${uiLabelMap.CommonFind}"><submit/></field>
</form>
<form name="ListFindStudent" list-name="listIt" title="" type="list" paginate-target="FindStudent"
odd-row-style="alternate-row" default-table-style="basic-table hover-bar">
<actions>
<service service-name="performFind" result-map="result" result-map-list="listIt">
<field-map field-name="inputFields" from-field="requestParameters"/>
<field-map field-name="entityName" value="Student"/>
<field-map field-name="viewIndex" from-field="viewIndex"/>
<field-map field-name="viewSize" from-field="viewSize"/>
<field-map field-name="noConditionFind" value="Y"/>
</service>
</actions>
<field name="stuId" title="${uiLabelMap.BookingStudentStuId}"><display/></field>
<field name="name" title="${uiLabelMap.BookingName}"><display/></field>
<field name="stuNumber" title="${uiLabelMap.BookingStudentStuNumber}"><display/></field>
<field name="class" title="${uiLabelMap.BookingStudentClass}"><display/></field>
<field name="sex" title="${uiLabelMap.BookingSex}">
<display description="${groovy: sex == 'Male' ? uiLabelMap.CommonMale : (sex == 'Female' ? uiLabelMap.CommonFemale : ' ')}"/>
</field>
<field name="resetPassword" title=" " widget-style="buttontext">
<hyperlink description="${uiLabelMap.BookingResetPassword}" target="resetPasswordForStudent" >
<parameter param-name="userLoginId" from-field="stuId"/>
</hyperlink>
</field>
<field name="updateLink" title=" " widget-style="buttontext">
<hyperlink description="${uiLabelMap.CommonUpdate}" target="EditStudent" >
<parameter param-name="stuId"/>
</hyperlink>
</field>
<field name="deleteLink" title=" " widget-style="buttontext">
<hyperlink description="${uiLabelMap.CommonDelete}" target="deleteStudent" also-hidden="false">
<parameter param-name="stuId"/>
</hyperlink>
</field>
</form>
<form name="EditStudent" target="updateStudent" title="" type="single" header-row-style="header-row"
default-table-style="basic-table" default-map-name="student" default-entity-name="Student">
<alt-target use-when="student==null" target="createStudent"/>
<auto-fields-service service-name="updateStudent" map-name=""/>
<field use-when="student!=null" name="stuId" title="${uiLabelMap.BookingStudentStuId}" tooltip="${uiLabelMap.BookingNotModification}." ><display/></field>
<field use-when="student==null" name="stuId" title="${uiLabelMap.BookingStudentStuId}" required-field="true"><text size="20" maxlength="20" /></field>
<field name="name" title="${uiLabelMap.BookingName}" required-field="true"><text size="20" maxlength="20" /></field>
<field name="stuNumber" title="${uiLabelMap.BookingStudentStuNumber}" required-field="true"><text size="20" maxlength="20" /></field>
<field name="class" title="${uiLabelMap.BookingStudentClass}" ><text size="20" maxlength="20" /></field>
<field name="sex" title="${uiLabelMap.BookingSex}">
<drop-down allow-empty="false" >
<option key="Male" description="${uiLabelMap.CommonMale}"/>
<option key="Female" description="${uiLabelMap.CommonFemale}"/>
</drop-down>
</field>
<field name="submitButton" title="${uiLabelMap.CommonSubmit}">
<submit/>
</field>
</form>
<form name="LookupStudent" target="LookupStudent" title="" type="single"
header-row-style="header-row" default-table-style="basic-table">
<!-- <auto-fields-entity entity-name="Student" default-field-type="hidden"/> -->
<field name="name" title="${uiLabelMap.BookingName}"><text-find/></field>
<field name="stuNumber" title="${uiLabelMap.BookingStudentStuNumber}"><text-find/></field>
<field name="class" title="${uiLabelMap.BookingStudentClass}"><text-find/></field>
<field name="sex" title="${uiLabelMap.BookingSex}">
<drop-down allow-empty="true" >
<option key="Male" description="${uiLabelMap.CommonMale}"/>
<option key="Female" description="${uiLabelMap.CommonFemale}"/>
</drop-down>
</field>
<field name="submitButton" title="${uiLabelMap.CommonFind}"><submit/></field>
</form>
<form name="ListLookupStudent" list-name="listIt" title="" type="list" paginate-target="LookupStudent"
odd-row-style="alternate-row" default-table-style="basic-table" view-size="20">
<actions>
<service service-name="performFind" result-map="result" result-map-list="listIt">
<field-map field-name="inputFields" from-field="requestParameters"/>
<field-map field-name="entityName" value="Student"/>
<field-map field-name="viewIndex" from-field="viewIndex"/>
<field-map field-name="viewSize" from-field="viewSize"/>
<field-map field-name="noConditionFind" value="Y"/>
</service>
</actions>
<field name="stuId" title="${uiLabelMap.BookingStudentStuId}" widget-style="buttontext">
<hyperlink description="${stuId}" target="javascript:set_value('${stuId}')" also-hidden="false" target-type="plain"/>
</field>
<field name="name" title="${uiLabelMap.BookingName}"><display/></field>
<field name="stuNumber" title="${uiLabelMap.BookingStudentStuNumber}"><display/></field>
<field name="class" title="${uiLabelMap.BookingStudentClass}"><display/></field>
<field name="sex" title="${uiLabelMap.BookingSex}"><display /></field>
</form>
<form name="ImportStudentsPage" target="ImportStudents" title="" type="upload" header-row-style="header-row"
default-table-style="basic-table" >
<field name="studentsFile" title=" " required-field="true"><file /></field>
<field name="submitButton" title="${uiLabelMap.CommonSubmit}">
<submit/>
</field>
</form>
</forms>
UserLogin.groovy(所在目录:hot-deploy\booking\groovyScripts)
import org.apache.ofbiz.entity.util.*
import org.apache.ofbiz.base.util.*
import org.apache.ofbiz.service.ServiceUtil
import javax.servlet.http.*
import org.apache.ofbiz.entity.GenericValue
import org.apache.ofbiz.entity.util.EntityFindOptions
import org.apache.ofbiz.entity.condition.EntityCondition
import org.apache.ofbiz.entity.condition.EntityConditionList
import org.apache.ofbiz.entity.condition.EntityExpr
import org.apache.ofbiz.entity.condition.EntityFieldValue
import org.apache.ofbiz.entity.condition.EntityFunction
import org.apache.ofbiz.entity.condition.EntityOperator
import org.apache.ofbiz.entity.util.EntityUtilProperties
/*
result = ServiceUtil.returnSuccess()
GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
String stuId = userLogin.userLoginId
//String stuId = context.stuId
result.successMessage = (String) "Got message [$stuId] and finished fine TEST GROOVY SERVICE"
result.result = batchId
return result
*/
//更新用户名字
public Map updateUserLoginName( ) {
GenericValue personGV = delegator.findOne("Person", false, UtilMisc.toMap("partyId", context.userLoginId))
if(personGV != null){
GenericValue studentGV = delegator.findOne("Student", false, UtilMisc.toMap("stuId", context.userLoginId))
if(studentGV != null){
personGV.set("firstName", studentGV.get("name"));
personGV.store();
}else{
GenericValue adminGV = delegator.findOne("Admin", false, UtilMisc.toMap("adminId", context.userLoginId))
personGV.set("firstName", adminGV.name);
personGV.store();
}
}
result = ServiceUtil.returnSuccess()
result.successMessage = (String) "用户名字修改成功!"
result.result = ""
return result
}
//重置密码
public Map resetPassword( ) {
GenericValue userLoginGV = delegator.findOne("UserLogin", false, UtilMisc.toMap("userLoginId", context.userLoginId))
if(userLoginGV != null){
userLoginGV.set("currentPassword",(String) "${'$SHA$ljj7AdyN7o$6DWvo7AP1swBcgf_pdeLufqGOck'}")
userLoginGV.set("requirePasswordChange", "Y")
userLoginGV.store()
}
result = ServiceUtil.returnSuccess()
result.successMessage = (String) "密码重置成功!"
result.result = ""
return result
}
//新增登录用户
public Map addUserLogin( ) {
GenericValue temp = delegator.findOne("UserLogin", false, UtilMisc.toMap("userLoginId", context.userLoginId))
if(temp != null){
temp.set("enabled", "Y")
temp.store()
//更新名字
Map personMap = UtilMisc.toMap("partyId", userLoginId, "firstName", context.name)
delegator.makeValue("Person", personMap).store();
//添加新权限
delegator.makeValue("UserLoginSecurityGroup", UtilMisc.toMap("groupId", context.role, "userLoginId", userLoginId,"fromDate",new java.sql.Timestamp(new java.util.Date().getTime()))).create();
}
else{
Map partyMap = UtilMisc.toMap("partyId", userLoginId, "partyTypeId", "PERSON", "statusId", "PARTY_ENABLED")
GenericValue partyGV = delegator.makeValue("Party", partyMap);
partyGV.create();
Map userLoginMap = UtilMisc.toMap("userLoginId", userLoginId,"partyId", userLoginId, "requirePasswordChange", "Y")
userLoginMap.put("currentPassword",(String) "${'$SHA$ljj7AdyN7o$6DWvo7AP1swBcgf_pdeLufqGOck'}")
userLoginMap.put("passwordHint","初始密码123456")
userLoginMap.put("lastLocale","zh")
GenericValue userLoginGV = delegator.makeValue("UserLogin", userLoginMap);
userLoginGV.create();
Map personMap = UtilMisc.toMap("partyId", userLoginId, "firstName", context.name)
delegator.makeValue("Person", personMap).create();
delegator.makeValue("UserLoginSecurityGroup", UtilMisc.toMap("groupId", context.role, "userLoginId", userLoginId,"fromDate",new java.sql.Timestamp(new java.util.Date().getTime()))).create();
}
result = ServiceUtil.returnSuccess()
result.successMessage = (String) "新增用户成功!"
result.result = "新增用户成功!"
return result
}
//删除账户
public Map deleteUserLogin( ) {
GenericValue userLoginGV = delegator.findOne("UserLogin", false, UtilMisc.toMap("userLoginId", context.userLoginId))
if(userLoginGV != null){
userLoginGV.set("enabled", "N")
userLoginGV.store()
}
List list = null;
//删除原有权限
list = delegator.findByAnd("UserLoginSecurityGroup", UtilMisc.toMap("userLoginId", userLoginId), null, false)
for(int i=0;i<list.size();i++){
list.get(i).remove()
}
result = ServiceUtil.returnSuccess()
result.successMessage = (String) "deleteUserLogin!"
result.result = "删除用户成功!"
return result
}
//批量导入学生
public String importStudents( ) {
HttpRequestFileUpload uploadObject = new HttpRequestFileUpload();
//uploadObject.setOverrideFilename("批量导入学生" + new Date().format("yyyy-MM-dd_HH_mm_ss") + ".xls");
String savePath = System.getProperty("user.dir") + "/runtime/output/";
uploadObject.setSavePath(savePath);
uploadObject.doUpload(request);
//获取上传上来的文件
result = ServiceUtil.returnSuccess()
result.successMessage = (String) "importStudents!"
context.successMessage = (String) "importStudents!"
result.result = "success"
File file = uploadObject.getFile("studentsFile")
if(file != null){
List list = ExcelUtil.readExcel(file);
for(int i=1;i<list.size();i++){
String [] cells = list.get(i);
Map studentMap = createStudentMap(cells);
GenericValue studentGV = delegator.findOne("Student", false, UtilMisc.toMap("stuId", studentMap.get("stuId")))
if (studentGV == null){
studentGV = delegator.makeValue("Student", studentMap)
studentGV.create()
}
}
}
else{
return "error"
}
return "success"
}
//
public Map createStudentMap(String[] cells) {
Map studentMap = UtilMisc.toMap("stuId", cells[0])
studentMap.put("stuNumber",cells[0])
studentMap.put("name",cells[1])
studentMap.put("class",cells[2])
if("男".equals(cells[3].trim()) ){
studentMap.put("sex","Male")
}else{
studentMap.put("sex","Female")
}
return studentMap
}
DownloadEvents.java
/*
* Created on 2017-10-27
*/
package org.apache.ofbiz.booking.download;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class DownloadEvents {
public static String download(HttpServletRequest request, HttpServletResponse response) throws Exception{
File f = new File(System.getProperty("user.dir") + "/hot-deploy/booking/template/学生信息导入模板.xlsx");
FileInputStream in = new FileInputStream(f);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename="+ new String(("学生信息导入模板" + ".xlsx").getBytes(), "iso-8859-1"));
response.setContentLength((int)f.length());
//fetch the file
int length = (int)f.length();
if(length != 0) {
byte[] buf = new byte[4096];
ServletOutputStream op = response.getOutputStream();
while ((in != null) && ((length = in.read(buf)) != -1)) {
op.write(buf,0, length);
}
in.close();
op.flush();
op.close();
}
//TODO: log hit
return "success";
}
}
学生信息管理的主要的代码实现就是以上这些。具体的代码讲解下章介绍。