`

jbpm3

阅读更多
JBPM学习笔记  

2012-01-05 14:06:00|  分类: JBPM |字号 订阅
一、如何在MyEclipse中安装JBPM插件

1、环境
系统:Win7
MyEclipse版本:7.5/8.0
Jbpm版本:4.4
2、步骤
①到jboss官网下载JBPM4.4,网址:http://sourceforge.net/projects/jbpm/files/
②将下载的JBPM4压缩包解压,将%JBPM_HOME%\install\src\gpd\jbpm-gpd-site.zip文件解压。
③点击MyEclipse8菜单:help-->software updates-->Add /remove software... ,在弹出的Add/Remove Software窗口中,单击add-->add Local-->找到上面解压后的%JBPM_HOME%\install\src\gpd\jbpm-gpd-site文件夹,点打开。可以看到就能加载成功了。
④在接下来的窗口中勾选jbpm中除以Sources结尾外的选项,接着点下一步,一路点下去直到提醒你重启,则插件安装成功。





注意:是勾选以Sources结尾以外的选项,否则安装会报错。
如果第3步的最后一个环节处(单击add-->add Local)还有类似add Archive的选项,则第一步不需将jbpm-gpd-site.zip文件解压,通过Archive直接选择jbpm-gpd-site.zip文件即可。

3、jbpm插件成功安装后,新建工程有个"jboss jBPM",可以新建一个文件,画流程图。

4、画流程图时候,可能会出现二个问题:

问题一:打开"window-show view-properties"页面有错误,因为我需要在这个页面上修改流程图中属性。

解决方法:从网上下载"site-1.6.10.zip"包,然后解压,把"features目录和plugins目录copy到myeclipse安装目录\myPlugin(自己建立的目录)\svn下,解压之后其他文件不需要。在然后到myeclipse安装目录\dropins下增加一个文件svn.link,该文件内容如下:

path=myeclipse安装目录\\myPlugin\\Svn

再然后把myeclipse安装目录下\configuration中的org.eclipse.update目录删除,最后重启myeclipse,一切ok了。

问题二:jbpm的xml文件中文是乱码

在myeclipse目录下找到myeclipse.ini文件,在文件结尾增加一行代码:

-Dfile.encoding=UTF-8

然后重启myeclipse,一切ok了。

二、JBPM与Myeclipse集成

英文版:

A、安装Eclipse插件:Graphical Process Designer(GPD),该插件已经包含在软件包中${jbpm.home}/install/src/gpd/jbpm-gpd-site.zip

1. Help --> Install New Software...

2.Click Add...

3.In dialog Add Site dialog, click Archive...

4.Navigate to install/src/gpd/jbpm-gpd-site.zip and click 'Open'

5.Clicking OK in the Add Site dialog will bring you back to the dialog 'Install'

6.Select the jPDL 4 GPD Update Site that has appeared

7.Click Next... and then Finish

8.Approve the license

9.Restart eclipse when that is asked

B、为Eclipse配置jBPM Runtime

1.Click Window --> Preferences

2.Select JBoss jBPM --> jBPM 4 --> Runtime Locations

3.Click Add...

4.In the Add Location dialog, enter a name like e.g. jbpm-4.0 and then click Search...

5.In the Browse For Folder dialog, select your jbpm home directory and click OK

6.Click OK in the Add Location dialog

C、为Eclipse添加用户库jBPM

1.Click Window --> Preferences

2.Select Java --> Build Path --> User Libraries

3.Click New...

4.Type name jBPM Libraries

5.Click Add JARs...

6.Navigate to the 'lib' folder of your jBPM installation

7.Select all jar files and click Open

8.Select the jBPM Libraries entry

9.Click Add JARs... again

10.Select the jbpm.jar file in the root of your jBPM installation

11.Click Open

12.Select entry Source attachment under jbpm.jar

//下列步骤是附加源码,不是必须的。

Click Edit

In dialog Source Attachment Configuration, click External Folder...

Navigate to the src folder in your jBPM installation

Click Choose

Click OK twice to close all the open dialogs

D、为了便于手工编辑XML的流程文件,为Eclispe添加schema文件

1.Click Window --> Preferences

2.Select XML --> XML Catalog

3.Click 'Add...'

4.The 'Add XML Catalog Entry' dialog opens

5.Click the button with the map-icon next to location and select 'File System...'

6.In the dialog that opens, select file jpdl-4.0.xsd in the src directory of the jBPM installation root.

7.Click 'Open' and close all the dialogs

E、导入示例项目

1.Select File --> Import...

2.Select General --> Existing Projects into Workspace

3.Click Next

4.Click Browse... to select a root directory

5.Navigate to the jBPM root installation directory

6.Click OK

7.The examples project is automatically found and selected

8.Click Finish

至此,所有例子都可以作为测试运行,右击所选项目:'Run As' --> 'JUnit Test'.

中文版:

使用jbpm时,有一个东东叫做图形化流程设计器,即Graph Process Designer(GPD),是用户能够通过图形拖拽,属性设置等可视化的方式进行业务流程设计,建立并展现业务流程模型。这个模型在jbpm4中一般为.jpdl.xml文件,遵循jpdl规范,此文件即“流程定义”文件,在运行时由工作流引擎解释执行,生成“流程实例”。

下面我们看看怎样用eclipse集成GPD,由于jbpm4 gpd集成eclipse有版本的限制,即eclipse3.5.x,所以我一咬牙就下了个myeclipse8.5,对应的eclipse版本为Eclipse 3.5.2,最开始以为这个版本肯定很慢,等装了之后,发觉部署和启动,都比6.0快,还不错。

myeclipse8.5的软件更新和前几个版本不太相同,首先Help-->Myeclipse Configuration Center,进去之后,点击SoftWare,然后Add from Archive File,选择 ${jbpm.home}/install/src/gpd/jbpm-gpd-site.zip文件,取个名字如 jbpmgpd,展开节点,点击右键,Add to Profile(不要带source的),最后点击Apply change,此时打开 window-

perferences里面会有一个jbpmgpd的栏目,重启OK。(这几步骤容易出错,小心行事,我试了一下,最好先把jboss配置好,在点击apply change的时候看看个数是否正确)。

成功后,会在window-->Preferences中看到 JBoss jBPM这个栏目。然后选择Runtime Locations来配置运行环境,点击add,输入名称如jbpm4.4,然后选择jbpm安装目录,ok。之后回到Runtime Location 选择jbpm4.4,点击OK,配置完成。

接下来为你的工作空间定义一个jbpm用户库(User Libraries),它可以被用来饮用jBPM的所有依赖库文件。如果你新建一个jBPM工程,只需将这个jBPM用户库添加到build path下即可。

1,选择 window-->Preferences

2,选择java -Build Path-User Libraries选项,单击New,输入名称 jBPM Libraries.

3,单击add jars,找到jbpm安装目录下的lib目录。

4,选择lib目录下的所有jar文件,并单击open按钮。

5,选中刚才新建的jBPM Libraries,重新单击add jars,在jbpm的安装目录下选择jbpm.jar文件

6,单击open

7,在jbpm.jar下选中Sourceattachment。

8,单击edit,在Source Attachement Configuration对话框中,单击External Folder按钮。

9,找到jBPM安装目录下的src目录。

10,单击choose按钮,为jbpm.jar关联源代码。

11,单击两次ok按钮关闭所有对话框,搞定。

添加jpdl4 schema校验,就像刚才说的jpdl是jbpm独有的流程定义语言,它以xml文件的形式描述业务流程。由于jbpm官方提供的图形化流程设计器功能不全面,因此很多情况下我们需要直接编辑jpdl的xml源代码,所以,最好为jpdl xml指定Schema,这样,可以通过快捷键"Alt+/"快速呼出语法提示,并帮你校验jpdl的语法错误。

在Eclipse中配置此Schema的过程是:

1,选择window-preferences,选择xml-->xml CataLog.

2,单击add,单击File System,然后选择${jbpm.home}/src/jpdl.xsd文件,ok,配置完成。

上面的整完之后呢,我们现在亲自动手,弄个程序跑跑,瞧好了。

在Jbpm4的软件包中,含有丰富的范例流程和测试代码,下面就将这些范例导入你的Eclipse中,成为一个examples工程,供学习和研究,步骤如下

file-->import,然后选择${jbpm.home}下的examples,ok完成。

配置了jbpm4用户依赖库后,范例中所有的单元测试类(都继承了JbpmTestCase)都可以作为Junit test运行了,在各个测试类上选择 run as-->JUnit Test命令即可。

当然,万能的ant也可以来帮你发布程序。首先,选择window-->show view-->other-->Ant-->Ant命令,打开ant试图;然后,将范例工程中的ant构建文件build.xml,从包视图拖拽到ant视图,即可使用其中的ant构建任务(target),来发布范例流程到目标服务器上,关于部署流程的细节,以后再讲。

现在,我们将设计一个最简单的流程定义 "HelloAfei"。

如下:

新建jbpm4 Process Definition,然后可以通过如下方式拖拽:





 

 

http://fndcz.iteye.com/blog/114436

http://www.iteye.com/topic/212671

http://duyunfei.iteye.com/blog/857793

http://www.iteye.com/topic/854291

 

三、JBoss JBPM实践系列

(一) 安装配置(Tomcat6.0+MySQL5.0)

jBPM,全称是Java Business Process Management,是一种基于J2EE的轻量级工作流管理系统。jBPM是公开源代码项目,遵循Apache License。jBPM在2004年10月18日,发布了2.0版本,并在同一天加入了JBoss,成为了JBoss企业中间件平台的一个组成部分,它的名称也改成JBoss jBPM。

jBPM有两大特色,使他成为市场的一大亮点。其中最大的特色就是它的业务逻辑定义没有采用目前的一些规范,如WfMC´s XPDL, BPML, ebXML, BPEL4WS等,而是它自己定义的JBoss jBPM Process definition language (jPdl)。jPdl把一个业务逻辑流程看作是一个UML状态图,如果你不熟悉UML状态图,那初学计算机语言的流程图应该熟悉吧,表达的方式和意思大同小异。jPdl详细定义了这个状态图的每个部分,如起始、结束状态,状态之间的转换等;其另一大特色就是集成Hibernate,确切的说是绑定,使用Hibernate来管理数据库,这样jBPM只专注于他的业务流程控制。

从上面可以看出,jBPM是一个业务流程管理引擎,是一个工作流引擎。除此之外,它同时实现了对jPDL和对BPEL的支持。它整合了Hibernate技术处理数据库,创建了一系列的数据库表,持久化工作流引擎所需的状态。因此,jBPM支持所有Hibernate支持的数据库,能够把Java对象持久化到数据库中,把Hibernate支持的Java类的对象保存到数据库中!

你完全可以像用 Java 的类库一样使用JBoss jBPM,而且通过配置JBoss jBPM也可以被部署在其它J2EE应用服务器上和任何数据库上。

在本文中,我们首先来创建我们的JBoss jBPM运行开发环境。在开始之前,请准备一下软件产品:

·JDK 1.5 或者更高版本, 这里使用JDK 6u10b

·Apache Tomcat 5.5.x或更高版本,这里使用Tomcat 6.0.16

·MySQL 5.1 ,也可以选择其它Hiberante 支持的数据库,没有太大差别,这里使用MySQL 5.1

·Apache Ant 1.7.0

·JBPM-3.2.3

·Eclipse Europa(Eclipse V3.3) for JavaEE Developers或更高, 这里使用Eclipse V3.4

说明:JBoss jBPM的发布包中已经配置好了一套服务环境,是基于JBoss的。因为我们习惯了Tomcat 的小巧灵活,而且我们也不希望jBPM依赖JBoss。

1. 下载安装JDK,Tomcat, Ant, MySQL, 并设置相应的环境变量

此步骤不再熬述,具体请查阅官方文档

Jdk:http://java.sun.com/

Ant:http://ant.apache.org/

Tomcat:http://tomcat.apache.org/

Eclipse:http://www.eclipse.org/

2. 下载JBoss jBPM

JBoss jBPM 官方(http://www.jboss.org/jbossjbpm/)当前发布的版本为 3.2.3, 只需要下载jPDL Suite,下载后得到jbpm-jpdl-suite-3.2.3.zip,这个套件包含了所有的内容和资源,包括eclipse插件,示例,和流程管理控制应用。

解压jbpm-jpdl-suite-3.2.3.zip,这里解压后得到D:\jbpm-jpdl-3.2.3,其主要目录结构如下:

D:\jbpm-jpdl-3.2.3

--- db   这里都是些sql定义和数据文件,如果改用其它数据库,可以使用这些资源来创建,服务还是很周到的。顺便啰嗦一句,jBPM 默认使用的是内存数据库 hsqldb ,这个数据库还没研究过

--- deploy  用来部署你的应用的包和资源

--- designer  这里是Eclipse插件,这样你就可以在图形界面来定义你的业务流程,骨灰级人物没他也能过日子

--- doc  这里是jBPM相关组件的API 文档

--- examples  这里是些学习的例子

--- lib  jBPM 的类库

--- server  这里有一个JBoss 服务器,并且包含了本JBoss jBPM引擎,还部署了websale例子

--- src  这里是JBoss  jBPM的源代码

安装Eclipse及jBPM开发插件

Eclipse不是开发 jBPM 必须的工具,但它是对 jBPM 开发很有帮助的工具,特别是 jBPM 提供了一个 Eclipse 插件用来辅助开发 jBPM 。关于 Eclipse 的安装请参阅相关文档。本实验安装的是MyEclipse6.0集成Eclipse3.3。

安装完Eclipse安装jBPM的开发插件,步骤如下:

(1) 打开Eclipse选择菜单“Help->Software Updates->Find and Install”;

(2) 弹出窗口中选择“Search for new features to install”,然后点击“Next >”;如图





 

 

(3) 点击按扭“New Local Site…”选择插件目录,位于designer\ eclipse目录下,如:E:\Java\tools\jbpm-jpdl-3.2.2\designer\eclipse。选定后点“OK”,如图





 

 

(4) 选中“designer/eclipse”,然后点击“Finish”,如图





 

 

(5) 然后选择同意条款,按提示步骤安装就可以了。

到此为止需要的所有工具都安装好了。接下来先体验一下jBPM工作流。在 jbpm-jpdl-3.2.2的 server 目录是一个已经在JBoss中配置好的了 jBPM 示例,双击 server 目录下的 start.bat 文件,启动 JBoss 服务。打开网页: http://localhost:8080/ jbpm-console 得到如下页面:




 

这是一个流程控制管理平台,用右边的账号与密码就可以登录,这个控制台包括流程管理,可以部署流程、删除流程、查看流程图、管理流程实例等;还有任务管理,工作管理及用户与用户组管理。

完成上述操作后,就可以创建JBoss jBPM项目了。在Eclipse中进行如下操作: File => new => Project 在项目类型中有一个“JBoss jBPM”点击展开选择“Process Project”=>输入项目名称(这里为:firstflow)=>Finish

现在你可以开始你的JBoss jBPM之旅了。在刚才新建的项目firstflow已经提供了一个简单的流程定义例子,打开src/main/jpdl/simple/processdifinition.xml 在右边编辑区就可以看到该流程定义的图形界面,左边就是设计器了。所有的GUI 设计器都是一样的用法,拖过来就可以用了,如果你在JBuilder等做过GUI开发这个就非常简单了(这里本身就没什么难度),也可以在 source 中直接编写代码来定义你的流程; src/main/jpdl/simple 下的 gpd.xml是用来定位你的图形设计组件的布局定位的,你不用去理会它,另外在Eclipse 菜单 View 中 选择 Show Grid ,你的设计器就会显示定位网格了,这样可以把组件摆的更美观;src/main/jpdl/simple 下的 processimage.jpg 就是你画的流程定义的结果图片了。 可以看出,你的工作就仅仅操作processdifinition.xml 来定义你的流程。

有了例子事情就容易多了,假如我们要建立一个自己的流程,可以在Eclipse 项目树 src/main/jpdl 右键 New => Other => 找到JBoss jBPM  展开后选择 Process Difinition => Next => 输入 Process Name (这里假设为fisrtflow) => Finish . OK, 你现在可以定义自己的流程了。

流程定义完成后,你可以在src/test 创建单元测试来测试你的代码,有现成的例子这里不多说了。一切都完成后,你就可以部署你的流程了。

你可以在D:\jbpm-jpdl-3.2.2\examples 找到各种Demo,这些官方的例子要比其它的地方的东西正宗,请阅读:jbpm-jpdl-suite-3.2.2\jbpm-jpdl-3.2.2\examples\readme.html,仔细看看相信你会有所收获。

3. 配置数据库(此处以MySQL为例,其他数据库方法一致)

jBPM需要把初始化数据和工作流定义存储到数据库中,它定义了一套数据结构来存储这些数据,这也是该容器本身的特点。

在mysql 中创建一个数据库 jbpm ,(create database jbpm;),并创建用户jbossjbpm(密码:jbossjbpm)

说明:如果你嫌麻烦可以使用root账号和其密码,不过下面的设置请做相应的更改。在D:\jbpm-jpdl-3.2.3\db 找到jbpm.jpdl.mysql.sql, 该文件必须修改一下,以符合MySQL的语法结构。具体就是在每条语句的末尾增加一个分号";"你可以借助 UltrEdit, EditPlus等工具来做这些事情(注意替换时要注意匹配大小写,有写表的字段中包含CREATE字符),如果是第一次创建这些数据库表,要删除create语句上面的alter和drop(这些表还都不存在)。

4. 准备jBPM包

这是个jbpm-jpdl流程管理控制台,就像Tomcat有个单独的Administrator应用用来管理配置和部署一样的东东。有了他你可以在图形界面来操作控制你的应用。

打开命令行控制台,切换到D:\jbpm-jpdl-3.2.2\deploy 目录,执行以下命令:

ant customize.console.for.tomcat

注意:请确保你的ant安装配置妥当,可以在命令行输入:ant -version 来检测ant 是否正确安装。命令执行后能看到ant的版本信息即OK

ant customize.console.for.tomcat 执行成功后,会在D:\jbpm-jpdl-3.2.2\deploy 目录下生成customized和target目录,其中customized目录下的jbpm-console.war即是我们想要的war包。

我们需要修改jbpm-console.war/WEB-INF/classes/hibernate.cfg.xml 文件,以适应我们的资源属性的需要。修改后的结果如下:

Xml代码

1.<hibernate-configuration>

2.  <session-factory>

3.

4.    <!-- hibernate dialect -->

5.    <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>

6.

7.    <!-- JDBC connection properties (begin) -->

8.    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>

9.    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jbpm</property>

10.    <property name="hibernate.connection.username">jbossjbpm</property>

11.    <property name="hibernate.connection.password">jbossjbpm</property>

12.     <!-- JDBC connection properties (end) -->

13.

14.    <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

15.

16.    <!-- DataSource properties (begin) ==

17.    <property name="hibernate.connection.datasource">java:/JbpmDS</property>

18.    == DataSource properties (end) -->

19.    <property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

20....

这里就是启用了更换了默认的数据属性,JDBC connection properties ,还有自己定义的数据名字和帐号,另外需要注意的是用

Xml代码

1.<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

代替JTATransactionFactory和CMTTransactionFactory,想用JTATransactionFactory或CMTTransactionFactory配置也可以,不过还没有研究过,有知道的朋友可以一起学习一下。

拷贝jboss-j2ee.jar包至jbpm-console.war/WEB-INF/lib 。发布包下(D:\jbpm-jpdl-3.2.2)很多地方都有这个包你可以找一下,比如 D:\jbpm-jpdl-3.2.2\server\client。

这里主要是用到了Java Transaction Architecture, 所以你可以用J2EE中的jta.jar包还替换jboss-j2ee.jar。jta相关信息请参考:http://java.sun.com/javaee/technologies/jta/index.jsp

拷贝commons-collections.jar 包至jbpm-console.war/WEB-INF/lib  。发布包下(D:\jbpm-jpdl-3.2.2)好几处都有这个包,比如 D:\jbpm-jpdl-3.2.2\server\server\jbpm\lib 。这个包是Apache Commons包,到处都找的的到。

拷贝jsf-api.jar和jsf-impl.jar包至jbpm-console.war/WEB-INF/lib ,你可以在D:\jbpm-jpdl-3.2.2\server\server\jbpm\deploy\jboss-web.deployer\jsf-libs种找到这两个包。

说明:因为jbpm-console是一个jsf应用,没这两个包,你访问时会报404或505错误。

拷贝MySQL JDBC驱动程序包至?TALINA_HOME%/lib(Tomcat 6)或?TALINA_HOME%/common/lib(Tomcat 5.5)

拷贝修改后的jbpm-console至?TALINA_HOME%/webapps

这样jBPM基本上配置完成,但是我们还不能访问他,还需要配置安全访问控制和初始的用户数据

5. 配置Tomcat 安全域

方法一:在?TALINA_HOME%/conf/Catalina/localhost 创建一个jbpm-console.xml 文件,内容如下:

Xml代码

1. <?xml version="1.0" encoding="UTF-8"?>

<Context>

2.<Realm  className="org.apache.catalina.realm.JDBCRealm"

3.    driverName="com.mysql.jdbc.Driver"

4.    connectionURL="jdbc:mysql://localhost:3306/jbpm"

5.    connectionName="jbossjbpm"

6.    connectionPassword="jbossjbpm"

7.    userTable="JBPM_ID_USER u, JBPM_ID_MEMBERSHIP m, JBPM_ID_GROUP g"

8.    userNameCol="g.TYPE_ = 'security-role' AND m.GROUP_ = g.ID_ AND m.USER_ = u.ID_ AND u.NAME_"

9.    userCredCol="DISTINCT u.PASSWORD_"

10.    userRoleTable="JBPM_ID_USER u, JBPM_ID_MEMBERSHIP m, JBPM_ID_GROUP g"

11.    roleNameCol="g.NAME_" />

12.</Context>

方法二:修改 ?TALINA_HOME%/conf/tomcat-users.xml文件来设置安全域。为了不和tomcat已有的用户冲突,这里把 tomcat以前的登陆帐号username="admin" 修改为username="tadmin",修改后的文件如下:

Xml代码

1.<?xml version='1.0' encoding='utf-8'?>

2.

3.<tomcat-users>

4.

5.  <role rolename="user"/>

6.

7.  <role rolename="administrator"/>

8.

9.  <role rolename="manager"/>

10.

11.  <role rolename="sales"/>

12.

13.  <role rolename="hr"/>

14.

15.  <role rolename="admin"/>

16.

17.  <role rolename="participant"/>

18.

19.  <user username="user" password="user" roles="user,sales"/>

20.

21.  <user username="shipper" password="shipper" roles="user,hr"/>

22.

23.  <user username="manager" password="manager" roles="admin,hr,manager,user,sales"/>

24.

25.  <user username="tadmin" password="" roles="admin,manager"/>

26.  <user username="admin" password="admin" roles="admin,user,hr"/>

27.</tomcat-users>

6. 初始化数据

在MySQL jbpm数据库中插入以下数据

Sql代码

1.INSERT INTO JBPM_ID_GROUP VALUES(1,'G','sales','organisation',NULL);

2.

3.INSERT INTO JBPM_ID_GROUP VALUES(2,'G','admin','security-role',NULL);

4.

5.INSERT INTO JBPM_ID_GROUP VALUES(3,'G','user','security-role',NULL);

6.

7.INSERT INTO JBPM_ID_GROUP VALUES(4,'G','hr','organisation',NULL);

8.

9.INSERT INTO JBPM_ID_GROUP VALUES(5,'G','manager','security-role',NULL);

10.

11.INSERT INTO JBPM_ID_USER VALUES(1,'U','user','user@sample.domain','user');

12.

13.INSERT INTO JBPM_ID_USER VALUES(2,'U','manager','manager@sample.domain','manager');

14.

15.INSERT INTO JBPM_ID_USER VALUES(3,'U','admin','admin@sample.domain','admin');

16.

17.INSERT INTO JBPM_ID_USER VALUES(4,'U','shipper','shipper@sample.domain','shipper');

18.

19.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(1,'M',NULL,NULL,2,4);

20.

21.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(2,'M',NULL,NULL,3,4);

22.

23.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(3,'M',NULL,NULL,4,4);

24.

25.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(4,'M',NULL,NULL,4,3);

26.

27.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(5,'M',NULL,NULL,1,3);

28.

29.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(6,'M',NULL,NULL,2,3);

30.

31.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(7,'M',NULL,NULL,3,3);

32.

33.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(8,'M',NULL,NULL,3,2);

34.

35.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(9,'M',NULL,NULL,2,2);

36.

37.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(10,'M',NULL,NULL,2,5);

38.

39.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(11,'M',NULL,'boss',2,1);

40.

41.INSERT INTO JBPM_ID_MEMBERSHIP VALUES(12,'M',NULL,NULL,1,1);

7. 启动Tomcat 服务,查看控制台的日志,排除错误,数据库错误和支持库不完整都可能导致错误。

在浏览器中输入:http://localhost:8080/jbpm-console  (注意这里的URL是你的tomcat的路径,依照具体的tomcat url输入) 能正常访问说明部署成功,你可以用页面上列出的用户和账号登陆进去体验一下。

8.打开网页:http://localhost:8080/jbpm-console 得到如下页面就说明已经部署成功:



 

用右边的manager账号登录,如下图:



点击“Deploy”转到部署流程页面,点击“浏览”按扭选择E:\Java\tools\jbpm-jpdl-3.2.2\examples\websale\target\websale.jpdl文件,名后点击“Deploy”按扭部署。

(二) 流程设计与部署

参考http://linliangyi2007.iteye.com/blog/176345

背景

本片文章,我们将从业务流程的设计开始,通过带领大家完成一个完整工作流的程序设计,来学习jPDL的使用。

业务流程设计

这里我们实现一个相对简化的公司借款申请流程。流程图如下:

 





 

在jPDL中,与流程设计相关的文件有三个:processdefinition.xml、gdp.xml、processimage.jpg。其中processdefinition.xml是流程定义的描述文件;gpd.xml是对图形界面呈现的XML描述;而processimage.jpg则是对图形界面的快照。下面我们将展示本样例的流程定义文件。

流程定义描述

processdefinition.xml文件

引用

<?xml version="1.0" encoding="UTF-8"?>

<process-definition   xmlns ="urn:jbpm.org:jpdl-3.2"  name="simple">

<start-state name="开始">

<transition name="借款发起" to="填写借款申请">

<action name="Action_StartProcess" class="com.firstflow.action.StartProcessActionHandler"></action>

</transition>

</start-state>

<task-node name="填写借款申请">

<task name="Task_AssignToInitiator">

<assignment class="com.firstflow.task.NewApplicationAssignmentHandler"></assignment>

</task>

<transition to="部门经理审批" name="提交申请">

<action name="Action_SubmitApply" class="com.firstflow.action.SubmitApplyActionHandler"></action>

</transition>

</task-node>

<task-node name="部门经理审批">

<task name="Task_ManagerApprove">

<assignment class="com.firstflow.task.DepartmentManagerApproveAssignmentHandler"></assignment>

</task>

<transition to="金额判定" name="部门经理审批通过">

<action name="Task_ManagerApproved" class="com.firstflow.action.ManagerApprovedActionHandler"></action>

</transition>

<transition to="结束" name="部门经理驳回">

<action name="Action_ManagerDisapprove" class="com.firstflow.action.ManagerDisapproveActionHandler"></action>

</transition>

</task-node>

<node name="财务拨款">

<action name="Action_AccountantProcess" class="com.firstflow.action.AccountantProcessActoinHandler"></action>

<transition to="结束" name="邮件通知">

<action name="Action_Mail" class="com.firstflow.action.SendMailActionHandler"></action>

</transition>

</node>

<decision name="金额判定">

<handler class="com.firstflow.decision.MoneyCheckDecisionHandler"></handler>

<transition to="总经理审批" name="&gt;5000元总经理审批"></transition>

<transition to="财务拨款" name="&lt;5000元 财务拨款"></transition>

</decision>

<task-node name="总经理审批">

<task name="Task_PresidentApprove">

<assignment class="com.firstflow.task.PresidentApproveAssignmentHandler"></assignment>

</task>

<transition to="财务拨款" name="总经理审批通过">

<action name="Action_PresidentApproved" class="com.firstflow.action.PresidentApprovedActionHandler"></action>

</transition>

<transition to="结束" name="总经理驳回">

<action name="Action_PresidentDisapproved" class="com.firstflow.action.PresidentDisapprovedActionHandler"></action>

</transition>

</task-node>

<end-state name="结束"></end-state>

</process-definition>

在样例流程中,除了开始和结束结点外,我们定义了三种类型的结点:

任务结点<task-node>

任务结点是一个需要人工参与的结点类型。当流程进入结点时,会生成相应的任务实例(TaskInstatnce),并通过委派接口AssignmentHandler或jBPM表达式将任务委派给一个或多个特定的角色或参与者。结点自身进入等待状态,直到任务被参与者完成或者跳过,流程继续。

判定结点<decision>

判定结点的设计目标是根据上下文环境和程序逻辑,判定流程转向。通过指定一个实现DecisionHandler接口的Java委派类或jBPM表达式,来返回转向(transition)的字符窜类型的名称(可以是中文哦),来达到决定流程方向的功能。

普通结点<node>

普通结点也可以定义相应的处理任务,通过定义相应的ActioinHandler类。同任务结点不同的是,普通结点定义的任务是由流程自动执行的,无须人工干预。

三种结点都可定义结点事件(event):

node-enter,该事件在流程进入结点时触发

node-leave,该事件在流程离开节点是触发

可以在事件上挂接ActioinHandler接口的实现类来完成一些特定的功能。

三种节点都可以定义异步处理方式(async属性):

异步处理意味着每个结点的事务处理是通过消息机制分离的,不再同一线程中统一调用执行。而是由消息监听线程从消息队列中取得消息体来运行相应得程序。

此外我们定义了结点间的转向(transition),用来记录和处理状态的变迁。每个转向中,可以委派一个或多个的ActioinHandler接口实现类,负责处理节点变迁时的上下文状态变更及回调用户定义的处理程序。

流程的程序接口说明

动作处理接口(ActioinHandler)

接口方法:void execute( ExecutionContext executionContext ) throws Exception

该接口是jPDL中最常用的一个回调接口。从它的接口方法可以发现,它仅仅暴露了流程执行上下文变量ExecutionContext。用户程序通过ExecutionContext来了解流程的执行状态,并通过改变ExecutionContext中的属性值来影响流程的执行。

ActioinHandler接口可以在所有能包含事件(event)、动作(action)元素的地方被回调。

判定处理接口(DecisionHandlder)

接口方法:String decide(ExecutionContext executionContext) throws Exception

判定接口仅适用于判定节点(decision)中。从它的接口方法可以看出,方法要返回一个字符串型的结果,这个结果必须和判定节点拥有的转向(transition)集合中的一条转向名称相匹配。

在DecisionHandlder的接口方法中一样能访问到ExecutionContext变量,这为判定提供了执行上下文的根据。当然,如果有必要,用户也可以在该接口中改变ExecutionContext中的变量值。

委派处理接口(AssignmentHandler)

接口方法:void assign(Assignable assignable, ExecutionContext executionContext) throws Exception;

委派处理接口被用户任务元素(task)的委派(assignment)子元素中,它的职责很明确,就是将任务分配给指定的人员或角色。

在AssignmentHandler接口的方法中,Assignable变量通常指任务实例(TaskInstance)。通过将ExecutionContext和TaskInstance两个变量都暴露给接口方法,用户就可以根据流程上下文情况,来决定要将指定的任务分配个谁。

流程的部署

用户使用jPDL的流程设计器定义业务流程,当然,你也可以直接用文档编辑器直接编辑processdefinition.xml定义文件。定义文档是可以直接被ProcessDefinition类载入使用的,但在正式运行的系统中,流程定义信息更多是使用关系型数据库来存储。从流程定义文件将数据导入流程数据库的过程,我们称之为流程部署。

jPDL的流程部署文件包含processdefinition.xml的定义部分和Java处理器的代码部分,这些文件可以被一起打包成.jpdl的zip格式包而后上传服务器端。这个过程可以在流程设计器界面的“deployment”标签页中操作:




这里我们着重要讲述的是接受部署文件上载的服务器端配置。在jBPM3.2的包中带着一个jPDL的管理控制台web应用,默认名字为jbpm-console。该应用带有接受流程定义包部署的程序,但不是最小化的。实际上完成流程部署功能的,只是jbpm-jpdl.jar核心包中的一个servlet类:org.jbpm.web.ProcessUploadServlet . 完成这个Servlet的成功部署,需要以下工作:

1. 配置web.xml,将servlet配置成启动时加载,如下:

引用

<web-app>

<servlet>

<servlet-name>GDP Deployer Servlet</servlet-name>

<servlet-class>org.jbpm.web.ProcessUploadServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>GDP Deployer Servlet</servlet-name>

<url-pattern>/upload

protected void deployProcessDefinition() throws Exception{

System.out.println("==FirstFlowProcessTest.deployProcessDefinition()==");

pdf = ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml");

assertNotNull("Definition should not be null", pdf);

}

 

protected void createProcessInstance(String user){

System.out.println("==FirstFlowProcessTest.createProcessInstance()==");

assertNotNull("Definition should not be null", pdf);

//生成实例

pi = pdf.createProcessInstance();

assertNotNull("processInstance should not be null", pi);

//设置流程发起人

pi.getContextInstance().createVariable("initiator", user);

//触发流程转向

pi.signal();

}

 

protected void submitApplication(int money){

System.out.println("==FirstFlowProcessTest.submitApplication()==");

TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next() ;

System.out.println("ti.actor = " + ti.getActorId());

ContextInstance ci = ti.getContextInstance();

ci.setVariable("money",new Integer(money));

ti.end();

}

 

@SuppressWarnings("unchecked")

protected void approveByManager(boolean pass){

System.out.println("==FirstFlowProcessTest.approveByManager()==");

Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator();

for( ;it.hasNext(); ){

TaskInstance ti = it.next();

if(ti.getActorId().equals("DepartmentManager")){

List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions();

for(Transition t : transitions){

System.out.println("----Transition" + t.getName());

}

assertEquals("DepartmentManager",ti.getActorId());

if(pass){

ti.end("部门经理审批通过");

}else{

ti.end("部门经理驳回");

}

return;

}

}

}

 

 

@SuppressWarnings("unchecked")

protected void approveByPresident(boolean pass){

System.out.println("==FirstFlowProcessTest.approveByPresident()==");

 

Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator();

 

for( ;it.hasNext(); ){

 

TaskInstance ti = it.next();

 

if(ti.getActorId().equals("President")){

List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions();

for(Transition t : transitions){

System.out.println("----Transition" + t.getName());

}

assertEquals("President",ti.getActorId());

if(pass){

ti.end("总经理审批通过");

}else{

ti.end("总经理驳回");

}

return;

}

}

}

 

@SuppressWarnings("unchecked")

protected void checkTasks(){

System.out.println("==FirstFlowProcessTest.checkTasks()==");

Collection<TaskInstance> coll = pi.getTaskMgmtInstance().getTaskInstances();

System.out.println("====Process has task:====");

for(TaskInstance ti : coll){

System.out.println("=="+ti.getName()+"==");

System.out.println("=="+ti.getActorId()+"==");

System.out.println("=="+ti.getVariables().toString() +"==");

}

System.out.println("====end====");

}

 

 

该案例是在没有数据库支持的情况下,对报销流程进行运行测试,测试逻辑如下:

 

1. 加载流程定义

Java代码

ProcessDefinition.parseXmlResource("firstflow/processdefinition.xml")

代码说明:

在没有数据库存储的情况下,流程定义通过ProcessDefinition类直接从processdefinition.xml文件中解析加载。

 

2. 实例化流程对象

Java代码

//生成实例

pi = pdf.createProcessInstance();

assertNotNull("processInstance should not be null", pi);

//设置流程发起人

pi.getContextInstance().createVariable("initiator", user);

//触发流程转向

pi.signal();

代码说明:

在获得流程定义的实例后,可以用它生成流程实例,使用如下的语句:

pi = pdf.createProcessInstance();

流程实例拥有自己的ContextInstance环境变量对象。它实际上是一个HashMap,以key-value方式记录了流程的上下文变量值,代码中的

pi.getContextInstance().createVariable("initiator", user);就是向环境变量中添加一个key为initiator的对象。

每个流程实例都拥有自己Token令牌对象,主流程有自己的RootToken,子流程也拥有自己的子Token。父流程的Token和子流程的Token相互关联,形成Token树。

Token对象表示流程运行的当前位置(运行到哪个节点了)。通过对Token对象的signal()方法调用,可以使流程向下运行。代码中的pi.signal();实际上是间接调用了pi.getRootToken().signal();它使得新建的流程继续向下个节点(即借款申请单填写)进发。

 

3. 员工发起借款申请

Java代码

 

protected void submitApplication(int money){

System.out.println("==FirstFlowProcessTest.submitApplication()==");

 

TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()

System.out.println("ti.actor = " + ti.getActorId());

ContextInstance ci = ti.getContextInstance();

ci.setVariable("money",new Integer(money));

ti.end();

代码说明:

在借款流程发起后,流程进入了申请单填写阶段。这个阶段是个人工的任务,需要用户的介入。因此,对于要借款的用户而言,首先是获取填写申请单的任务实例:

TaskInstance ti = (TaskInstance)pi.getTaskMgmtInstance().getTaskInstances().iterator() .next()

在这个测试类中,由于没有数据库。对流程实例的引用是依靠了类的全局标量pi。这里通过pi获取全部的任务列表。实际上有且仅有一个任务,就是我们刚刚发起的申请单填写任务。

接下来,我们获取流程的上下文变量,将申请借款的数额记录在上下文变量中ContextInstance ci = ti.getContextInstance();

ci.setVariable("money",new Integer(money));

最后,我们要结束当前任务,告诉流程继续下行,调用ti.end();这个方法的本质依然是调用了token.signal(),它选择了一个默认的transition进行转向。这里要说明的是signal方法有多态的实现signal(Transition  transition),是可以指定具体转向参数的。

 

4. 部门领导审批申请

Java代码

 

@SuppressWarnings("unchecked")

protected void approveByManager(boolean pass){

System.out.println("==FirstFlowProcessTest.approveByManager()==");

Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator();

for( ;it.hasNext(); ){

TaskInstance ti = it.next();

if(ti.getActorId().equals("DepartmentManager")){

List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions();

for(Transition t : transitions){

System.out.println("----Transition" + t.getName());

}

assertEquals("DepartmentManager",ti.getActorId());

if(pass){

ti.end("部门经理审批通过");

}else{

ti.end("部门经理驳回");

}

return;

}

}

}

代码说明:

这里,流程进入了部门经理审批阶段。由于没有数据库支持,我们只能采取遍历任务列表,并比对委派者ID的方式来确定委派给部门经理的任务实例。(在后面的基于数据库的标准案例中,我们会看到如果根据用户的ID来获取分配给指定用户的任务)

ti.getActorId().equals("DepartmentManager") // 比对任务的委派人。

ti.getToken().getNode().getLeavingTransitions();//获取任务在当前节点上的所有转向。

这里我们要特别指出的是ti.end("部门经理审批通过")和ti.end("部门经理驳回")这实际上调用token.signal(transition);来完成任务的转向,从而使流程继续。

 

5. 总经理审批申请

Java代码

 

@SuppressWarnings("unchecked")

protected void approveByPresident(boolean pass){

System.out.println("==FirstFlowProcessTest.approveByPresident()==");

Iterator<TaskInstance> it = pi.getTaskMgmtInstance().getTaskInstances().iterator();

 

for( ;it.hasNext(); ){

TaskInstance ti = it.next();

if(ti.getActorId().equals("President")){

List<Transition> transitions = ti.getToken().getNode().getLeavingTransitions();

for(Transition t : transitions){

System.out.println("----Transition" + t.getName());

}

assertEquals("President",ti.getActorId());

if(pass){

ti.end("总经理审批通过");

}else{

ti.end("总经理驳回");

}

return;

}

}

}

代码说明:

此步代码同“部门经理审批”代码相似,不作更多说明。

 

标准流程测试案例

 

该案例模拟了标准运行环境中,基于关系型数据库的jBPM系统是如何执行流程的。

测试案例类:FirstFlowProcessDBTest.java

Java代码

public class FirstFlowProcessDBTest {

 

static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();

public static void main(String[] args){

FirstFlowProcessDBTest test = new FirstFlowProcessDBTest();

test.test4000YuanApplication();

test.test6000YuanApplication();

test.test7000YuanApplication();

}

 

public void test4000YuanApplication(){

ProcessInstance pi = createProcessInstance("linly");

submitApplication("linly" , 4000);

approveByManager(true);

checkTasks(pi);

}

public void test6000YuanApplication() {

ProcessInstance pi = createProcessInstance("linly");

submitApplication("linly" , 6000);

approveByManager(true);

approveByPresident(true);

checkTasks(pi);

}

public void test7000YuanApplication() {

ProcessInstance pi = createProcessInstance("linly");

submitApplication("linly" , 7000);

approveByManager(true);

approveByPresident(false);

checkTasks(pi);

}

 

protected ProcessInstance createProcessInstance(String user){

System.out.println("==FirstFlowProcessTest.createProcessInstance()==");

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try {

GraphSession graphSession = jbpmContext.getGraphSession();

 

ProcessDefinition pdf  = graphSession.findLatestProcessDefinition("simple");

//生成流程实例

ProcessInstance pi = pdf.createProcessInstance();

//设置流程发起人

pi.getContextInstance().createVariable("initiator", user);

//触发流程转向

pi.signal();

 

jbpmContext.save(pi);

return pi;

}finally{

jbpmContext.close();

}

}

 

 

@SuppressWarnings("unchecked")

protected void submitApplication(String actorId , int money){

System.out.println("==FirstFlowProcessTest.submitApplication()==");

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try {

 

List<TaskInstance> taskInstances = jbpmContext.getTaskList(actorId);

for(TaskInstance ti : taskInstances){

System.out.println("ti.name = " + ti.getName());

System.out.println("ti.actor = " + ti.getActorId());

ContextInstance ci = ti.getContextInstance();

ci.setVariable("money",new Integer(money));

ti.end();

}

}finally{

jbpmContext.close();

}

}

 

 

@SuppressWarnings("unchecked")

protected void approveByManager(boolean pass){

System.out.println("==FirstFlowProcessTest.approveByManager()==");

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try{

List<TaskInstance> taskInstances = jbpmContext.getTaskList("DepartmentManager");

for(TaskInstance ti : taskInstances){

System.out.println("ti.name = " + ti.getName());

System.out.println("ti.actor = " + ti.getActorId());

if(pass){

ti.end("部门经理审批通过");

}else{

ti.end("部门经理驳回");

}

}

}finally{

jbpmContext.close();

}

}

 

 

@SuppressWarnings("unchecked")

protected void approveByPresident(boolean pass){

System.out.println("==FirstFlowProcessTest.approveByPresident()==");

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try{

List<TaskInstance> taskInstances = jbpmContext.getTaskList("President");

for(TaskInstance ti : taskInstances){

System.out.println("ti.name = " + ti.getName());

System.out.println("ti.actor = " + ti.getActorId());

if(pass){

ti.end("总经理审批通过");

}else{

ti.end("总经理驳回");

}

}

}finally{

jbpmContext.close();

}

}

 

 

@SuppressWarnings("unchecked")

protected void checkTasks(ProcessInstance pi){

System.out.println("==FirstFlowProcessTest.checkTasks()==");

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try{

List<TaskInstance> coll = jbpmContext.getTaskMgmtSession().findTaskInstancesByProcessInstance(pi);

System.out.println("====Process has task:====");

for(TaskInstance ti : coll){

System.out.println("=="+ti.getName()+"==");

System.out.println("=="+ti.getActorId()+"==");

System.out.println("=="+ti.getVariables().toString() +"==");

}

System.out.println("====end====");

}finally{

jbpmContext.close();

}

}

}

 

相对于简单流程测试案例,标准流程的业务是相同的。它们的不同点在于:简单流程通过XML载入流程定义,并使用类的全局变量来保存流程实例的引用;而标准流程则是通过数据库载入流程定义,并使用数据库的会话来维护流程的运行。

 

1. 从数据库载入流程定义

Java代码

?   JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

从jBPM配置环境中获取jBPM上下文实例,jbpmContext是对jbpm持久层操作API及上下文环境的封装,它根据jBPM的配置文件生成。

?

Java代码

GraphSession graphSession = jbpmContext.getGraphSession();

生成对流程图操作的持久层会话

?

Java代码

ProcessDefinition pdf  = graphSession.findLatestProcessDefinition("simple");

从数据库获取命名为“simple”的流程定义。

 

2. 新建流程实例,并存入数据库持久化

?

Java代码

ProcessInstance pi = pdf.createProcessInstance();

根据流程定义生成实例。

?

Java代码

pi.getContextInstance().createVariable("initiator", user);

pi.signal();

 

设置实例的上下文变量,激活实例执行进程。

?

Java代码

jbpmContext.save(pi);

 

保存实例到数据库,持久化实例。

 

3. 从数据库获取属于指定操作者的任务集

Java代码

JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();

try{

List<TaskInstance> taskInstances = jbpmContext.getTaskList("DepartmentManager");

for(TaskInstance ti : taskInstances){

System.out.println("ti.name = " + ti.getName());

System.out.println("ti.actor = " + ti.getActorId());

if(pass){

ti.end("部门经理审批通过");

}else{

ti.end("部门经理驳回");

}

}

}finally{

jbpmContext.close();

}

通过JbpmContext对象,从数据库获取指定操作者的任务集合:

Java代码

List<TaskInstance> taskInstances = jbpmContext.getTaskList("DepartmentManager");

注意,在每次的JbpmContext对象使用完毕后,一定要执行jbpmContext.close(),其本质是要释放数据库的操作连接。





http://blog.163.com/magicc_love/blog/static/185853662201205260843/
分享到:
评论

相关推荐

    安卓选择器类库,包括日期及时间选择器(可用于出生日期、营业时间等)

    安卓选择器类库,包括日期及时间选择器(可用于出生日期、营业时间等)、单项选择器(可用于性别、民族、职业、学历、星座等)、二三级联动选择器(可用于车牌号、基金定投日期等)、城市地址选择器(分省级、地市级及区县级)、数字选择器(可用于年龄、身高、体重、温度等)、日历选日期择器(….zip

    整个系统采用 Java 语言基于 Spring 全家桶,与MySQL数据库等相结合开发

    虽然现如今电商行业发展迅速,平台成熟,但是小的个体商家想要在头部电商平台中交易还是代价很高,各种供应链拖欠货款层出不穷,当客户和平台由于商品问题产生纠纷后,平台整体会倾向于客户处理,总之,还是要有自己的商城系统,构成所谓的两条腿发展,做到既可以利用第三方平台销售,也需要自己建立平台。我们开发的乐优商城,具备全品类商品的买卖能力,并且组建了一整套高性能服务,可以实现高并发高可用,满足电商的各种促销。为中小企业全方位解决搭建交易平台的难题。 乐优商城开发功能目标: 1、 商品管理模块:实现商品分类,品牌,规格参数,商品自身管理,商 品的上架,下架处理。 2、 搜索系统:基于 elasticSearch 实现商品搜索,搜索自动提示,高亮, 排序,搜索过滤。 3、登录系统:实现用户的登录以及登出,过期时间刷新。 4、购物车系统:基于 SpringData 及 MongoDB 实现购物车增删改查。 5、下单系统:下单减库存,使用分布式事务解决方案 Seata 6、支付系统:调用第三方电子支付平台完成支付及回调,动态修改订单 状态为已支付,为后续发货物流,做好保障工作。

    毕业设计+Python+基于OpenCV的交通路口红绿灯控制系统设计+Sqlite +PyCharm 8.zip.zip

    本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!! 本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!! 本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!

    Java毕业设计-基于Springboot+Vue水果购物网站源码+数据库+PPT文档+演示视频(高分项目).zip

    Java毕业设计-基于Springboot+Vue水果购物网站源码+数据库+PPT文档+演示视频(高分项目).zip该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到97分,在window10/11测试环境严格调试,下载即用,确保可以运行,部署教程齐全,也可以作为期末作业。 Java毕业设计-基于Springboot+Vue水果购物网站源码+数据库+PPT文档+演示视频(高分项目).zip该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到97分,在window10/11测试环境严格调试,下载即用,确保可以运行,部署教程齐全,也可以作为期末作业。 Java毕业设计-基于Springboot+Vue水果购物网站源码+数据库+PPT文档+演示视频(高分项目).zip该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到97分,在window10/11测试环境严格调试,下载即用,确保可以运行,部署教程齐全,也可以作为期末作业。Java毕业设计-基于Springboot+Vue水果购物网站源码+数据库+PPT文档+演示视频(高分项目

    浙江财经大学东方学院-论文PPT模板我给母校送模板作品.pptx

    PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。

    node-v13.13.0-linux-armv7l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    修复windows系统库软件

    windows系统,安装软件后,经常会遇到缺少系统库的情况,通常有三种方法 方法2:修复系统库。双击运行这个软件即可自动修复。

    基于matlab的说话人语音识别源码+PPT+报告(优质项目).zip

    基于matlab的说话人语音识别源码+PPT+报告(优质项目).zip个人经导师指导并认可通过的98分毕业设计项目,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者。也可作为课程设计、期末大作业。包含全部项目源码、该项目可以直接作为毕设使用。项目都经过严格调试,确保可以运行! 基于matlab的说话人语音识别源码+PPT+报告(优质项目).zip个人经导师指导并认可通过的98分毕业设计项目,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者。也可作为课程设计、期末大作业。包含全部项目源码、该项目可以直接作为毕设使用。项目都经过严格调试,确保可以运行! 基于matlab的说话人语音识别源码+PPT+报告(优质项目).zip个人经导师指导并认可通过的98分毕业设计项目,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者。也可作为课程设计、期末大作业。包含全部项目源码、该项目可以直接作为毕设使用。项目都经过严格调试,确保可以运行!基于matlab的说话人语音识别源码+PPT+报告(优质项目).zip个人经导师指导并认可通过的98分毕业

    2020年美国大学生数学建模竞赛C题代码.zip

    最全的数学建模美赛C题和代码、大量刷题题库、逻辑清晰易于学习

    2024年全球无尘料斗装载机行业总体规模、主要企业国内外市场占有率及排名.docx

    2024年全球无尘料斗装载机行业总体规模、主要企业国内外市场占有率及排名

    基于STM32单片机的智能停车场设计源码+全部资料.zip

    基于STM32单片机的智能停车场设计源码+全部资料(优质毕业设计).zip主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者。也可作为课程设计、期末大作业。包含全部项目源码、该项目可以直接作为毕设使用。项目都经过严格调试,确保可以运行

    user+name.csv

    user+name.csv

    2022年机动车车牌识别挑战赛Top1方案.zip

    2022年机动车车牌识别挑战赛Top1方案.zip

    济南大学-答辩PPT模板我给母校送模板作品.pptx

    PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。

    2024-2030全球与中国中空纤维膜市场现状及未来发展趋势.docx

    2024-2030全球与中国中空纤维膜市场现状及未来发展趋势

    NIUCLOUD-ADMIN 是一款快速开发SaaS通用管理系统后台框架.zip

    springboot框架 一、Spring Boot基础应用 Spring Boot特征 概念: 约定优于配置,简单来说就是你所期待的配置与约定的配置一致,那么就可以不做任何配置,约定不符合期待时才需要对约定进行替换配置。 特征: 1. SpringBoot Starter:他将常用的依赖分组进行了整合,将其合并到一个依赖中,这样就可以一次性添加到项目的Maven或Gradle构建中。 2,使编码变得简单,SpringBoot采用 JavaConfig的方式对Spring进行配置,并且提供了大量的注解,极大的提高了工作效率,比如@Configuration和@bean注解结合,基于@Configuration完成类扫描,基于@bean注解把返回值注入IOC容器。 3.自动配置:SpringBoot的自动配置特性利用了Spring对条件化配置的支持,合理地推测应用所需的bean并自动化配置他们。 4.使部署变得简单,SpringBoot内置了三种Servlet容器,Tomcat,Jetty,undertow.我们只需要一个Java的运行环境就可以跑SpringBoot的项目了

    085ssm-vue大学生兼职跟踪系统.zip(可运行源码+数据库文件+文档)

    L文主要是对大学生兼职跟踪系统进行了介绍,包括研究的现状,还有涉及的开发背景,然后还对系统的设计目标进行了论述,还有系统的需求,以及整个的设计方案,对系统的设计以及实现,也都论述的比较细致,最后对大学生兼职跟踪系统进行了一些具体测试。 本文以Java为开发技术,实现了一个大学生兼职跟踪系统。大学生兼职跟踪系统的主要实现功能包括:管理员:首页、个人中心、商家管理、学生管理、兼职招聘管理、兼职应聘管理、商家投诉管理、投诉处理管理、论坛管理、系统管理等等。学生后台模块:首页、个人中心、兼职应聘管理、商家投诉管理、我的收藏管理,商家;首页、个人中心、兼职招聘管理、兼职应聘管理、投诉处理管理等等通过这些功能模块的设计,学生前台:首页、兼职招聘、兼职论坛、系统公告、我的、跳转到后台。基本上实现了整个大学生兼职跟踪系统的过程。 具体在系统设计上,采用了B/S的结构,同时,也使用Java技术在动态页面上进行了设计,后台上采用Mysql数据库,是一个非常优秀的大学生兼职跟踪系统。 关键词 :大学生兼职跟踪系统;Java技术;Mysql数据库;B/S结构

    开发 bilibili 网站爬虫,大数据分析研究.zip

    开发 bilibili 网站爬虫,大数据分析研究.zip

    WinCE工具和小软件合集包括计算器闹钟电子阅读器万年历画图工具词典等(58款).zip

    WinCE工具和小软件合集包括计算器闹钟电子阅读器万年历画图工具词典等(58款): ToWinCe.exe WinCE内存释放工具 WinCE桌面工具软件Explorer WINCE浏览器 WinCE软件合集大全(60款).zip YFGo2CE.rar 一体机全屏手写输入法 任务管理 修改端口程序 关机.exe 内存清理.exe 内存释放.exe 内存释放.rar 切换软件工具 、图片预览 媒体播放 工具-中文汉化版 幻 灯 开关任务栏-移动窗口 截图工具 手写板 掌心万年历 文件检查 文件管理 文本编辑器 文本转换 新远峰机器有硬关机了 日程安排 显示速度 显示速度、经纬度,高度的小工具 替代SQ的精编软件ST(有桌面版) 极品时刻表 极品火车时刻表 桌面透明 注册表编辑器 浏览器.exe 海鹰完美版(含五笔、拼音、符号) 海鹰输入法 清理内存工具 游戏 环境优化 电子阅读器HaaliReader 画图工具 福昕浏览器 系统信息 虚拟键盘 计算器 记事本 词典 语音阅读器 调出输入法 资源管理 资源管理.exe 进程管理.exe 重启.exe 闹 钟 黄历

    实验三-进程通信(一).doc

    实验三-进程通信(一).doc

Global site tag (gtag.js) - Google Analytics