根据SVN信息自动生成升级补丁包

十二月 3, 2010 作者:admin  
类别:JAVA开发

/**
 * 使用说明:
 * 注意:在使用之前需保证本地和SVN上的数据保持一致。
 *
 * 使用方法:
 * 1. 查看SVN日志,将日志复制到一个文本文件 war.txt 中
 * 2. 配置参数,需对以下几个参数进行配置:(对于目录路径可以不用斜杠结尾)
 *    destPath:  生成的打包文件夹。
 *    workPath:  服务器下部署目录。
 * 3. 执行完成之后,查看日志 log/fatwar.log 如果没有任何异常且没有错误提示信息(在最后),则表示执行成功。
 *    如果执行成功,那么在日志中最后会提示生成的打包地址。
 */
public class FatWarMain
{
private final static Logger log = LogManager.getLogger(FatWarMain.class);
public static String destPath = null; // 放生成的WAR路径
public static String txtPath = “war.txt”; // 将SVN信息复制到该文本文件中
public static String workPath = null; // 注意此目录需配置为服务器目录,eclipse工作目录可能不存在JSP文件
public static void main(String[] args)
{
setResourceAttributeValue();
if (workPath == null || “”.equals(workPath))
{
log.info(“请配置参数,参数值不能为空!”);
return;
}
if (!new File(workPath).exists())
{
log.info(“指定服务器部署目录不存在,请检查路径是否正确!”);
return;
}
log.info(“destPath:” + destPath + ” workPath:” + workPath);
StringBuffer errinfo = new StringBuffer();
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(txtPath));
String string = null;
while ((string = reader.readLine()) != null)
{
log.info(“SVN信息:” + string);
if (string.contains(“/ProductCode/”))
{
String filename = string.substring(string.lastIndexOf(‘/’) + 1);
log.info(“获取文件名:” + filename);
if (filename.endsWith(“.java”)) // 编译之后生成class文件,且要考虑内部类的情况
{
final String temp = filename.substring(0, filename.indexOf(“.java”)); // 去掉扩展名之后的文件名
String classDir = workPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12, string.lastIndexOf(‘/’));
final String destDir = destPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12, string.lastIndexOf(‘/’));
File[] files = new File(classDir).listFiles(new FileFilter() {
public boolean accept(File file)
{
if (file.getName().equals(temp + “.class”) || file.getName().startsWith(temp + “$”))
{
String dest = destDir + “/” + file.getName();
log.info(“原文件路径:” + file.getPath());
log.info(“目标文件路径:” + dest);
Handle.copyFile(file, new File(dest));
return true;
}
return false;
}});
if (files.length == 0)
{
log.warn(“在路径 ” + classDir + ” 下找不到编译之后的文件,源文件名:” + filename);
errinfo.append(“SVN信息:” + string + “\n在路径 ” + classDir + ” 下找不到编译之后的文件,源文件名:” + filename + “\n”);
}
log.info(“该SVN信息处理完成!\n”);
}
else // 对于其他类型文件
{
String sourceFile = workPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12);
String destFile = destPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12);
log.info(“原文件路径:” + sourceFile);
log.info(“目标文件路径:” + destFile);
Handle.copyFile(new File(sourceFile), new File(destFile));
log.info(“该SVN信息处理完成!\n”);
}
}
else if (string.contains(“/WebContent/”))
{
String sourceFile = workPath + string.substring(string.indexOf(“/WebContent/”) + 11);
String destFile = destPath + string.substring(string.indexOf(“/WebContent/”) + 11);
log.info(“原文件路径:” + sourceFile);
log.info(“目标文件路径:” + destFile);
Handle.copyFile(new File(sourceFile), new File(destFile));
log.info(“该SVN信息处理完成!\n”);
}
else if (string.trim().length() > 0)
{
log.warn(“该SVN信息不能被解析!\n”);
errinfo.append(“\nSVN信息:” + string + “\n该SVN信息不能被解析!\n”);
}
}
String errorinfostr = errinfo.toString();
if (errorinfostr.length() > 0)
{
log.error(“\n以下是错误信息:\n” +
“————————————————————————————————————————-” +
errorinfostr);
}
else
{
log.info(“运行成功,打包地址:” + destPath);
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (reader != null)
{
reader.close();
}
}
catch (IOException e)
{
}
}
}
public static void setResourceAttributeValue()
{
BufferedReader reader = null;
String string = “”;
try
{
reader = new BufferedReader(new FileReader(“config/res.txt”));
boolean b = false;
while ((string = reader.readLine()) != null)
{
String key = string.substring(0, string.indexOf(‘=’));
String value = string.substring(string.indexOf(‘=’) + 1).trim();
if (key.equals(“destPath”))
{
FatWarMain.destPath = value;
b = true;
}
if (key.equals(“workPath”))
{
FatWarMain.workPath = value;
}
}
if (!b)
{
FatWarMain.destPath = String.valueOf(new Date().getTime());
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (reader != null)
{
reader.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}

/**

 * 使用说明:

 * 注意:在使用之前需保证本地和SVN上的数据保持一致。

 *

 * 使用方法:

 * 1. 查看SVN日志,将日志复制到一个文本文件 war.txt 中

 * 2. 配置参数,需对以下几个参数进行配置:(对于目录路径可以不用斜杠结尾)

 *    destPath:  生成的打包文件夹。

 *    workPath:  服务器下部署目录。

 * 3. 执行完成之后,查看日志 log/fatwar.log 如果没有任何异常且没有错误提示信息(在最后),则表示执行成功。

 *    如果执行成功,那么在日志中最后会提示生成的打包地址。

 */

public class FatWarMain

{

private final static Logger log = LogManager.getLogger(FatWarMain.class);

public static String destPath = null; // 放生成的WAR路径

public static String txtPath = “war.txt”; // 将SVN信息复制到该文本文件中

public static String workPath = null; // 注意此目录需配置为服务器目录,eclipse工作目录可能不存在JSP文件

public static void main(String[] args)

{

setResourceAttributeValue();

if (workPath == null || “”.equals(workPath))

{

log.info(“请配置参数,参数值不能为空!”);

return;

}

if (!new File(workPath).exists())

{

log.info(“指定服务器部署目录不存在,请检查路径是否正确!”);

return;

}

log.info(“destPath:” + destPath + ” workPath:” + workPath);

StringBuffer errinfo = new StringBuffer();

BufferedReader reader = null;

try

{

reader = new BufferedReader(new FileReader(txtPath));

String string = null;

while ((string = reader.readLine()) != null)

{

log.info(“SVN信息:” + string);

if (string.contains(“/ProductCode/”))

{

String filename = string.substring(string.lastIndexOf(‘/’) + 1);

log.info(“获取文件名:” + filename);

if (filename.endsWith(“.java”)) // 编译之后生成class文件,且要考虑内部类的情况

{

final String temp = filename.substring(0, filename.indexOf(“.java”)); // 去掉扩展名之后的文件名

String classDir = workPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12, string.lastIndexOf(‘/’));

final String destDir = destPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12, string.lastIndexOf(‘/’));

File[] files = new File(classDir).listFiles(new FileFilter() {

public boolean accept(File file)

{

if (file.getName().equals(temp + “.class”) || file.getName().startsWith(temp + “$”))

{

String dest = destDir + “/” + file.getName();

log.info(“原文件路径:” + file.getPath());

log.info(“目标文件路径:” + dest);

Handle.copyFile(file, new File(dest));

return true;

}

return false;

}});

if (files.length == 0)

{

log.warn(“在路径 ” + classDir + ” 下找不到编译之后的文件,源文件名:” + filename);

errinfo.append(“SVN信息:” + string + “\n在路径 ” + classDir + ” 下找不到编译之后的文件,源文件名:” + filename + “\n”);

}

log.info(“该SVN信息处理完成!\n”);

}

else // 对于其他类型文件

{

String sourceFile = workPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12);

String destFile = destPath + “/WEB-INF/classes” + string.substring(string.indexOf(“/ProductCode/”) + 12);

log.info(“原文件路径:” + sourceFile);

log.info(“目标文件路径:” + destFile);

Handle.copyFile(new File(sourceFile), new File(destFile));

log.info(“该SVN信息处理完成!\n”);

}

}

else if (string.contains(“/WebContent/”))

{

String sourceFile = workPath + string.substring(string.indexOf(“/WebContent/”) + 11);

String destFile = destPath + string.substring(string.indexOf(“/WebContent/”) + 11);

log.info(“原文件路径:” + sourceFile);

log.info(“目标文件路径:” + destFile);

Handle.copyFile(new File(sourceFile), new File(destFile));

log.info(“该SVN信息处理完成!\n”);

}

else if (string.trim().length() > 0)

{

log.warn(“该SVN信息不能被解析!\n”);

errinfo.append(“\nSVN信息:” + string + “\n该SVN信息不能被解析!\n”);

}

}

String errorinfostr = errinfo.toString();

if (errorinfostr.length() > 0)

{

log.error(“\n以下是错误信息:\n” +

“————————————————————————————————————————-” +

errorinfostr);

}

else

{

log.info(“运行成功,打包地址:” + destPath);

}

}

catch (FileNotFoundException e)

{

e.printStackTrace();

}

catch (IOException e)

{

e.printStackTrace();

}

finally

{

try

{

if (reader != null)

{

reader.close();

}

}

catch (IOException e)

{

}

}

}

public static void setResourceAttributeValue()

{

BufferedReader reader = null;

String string = “”;

try

{

reader = new BufferedReader(new FileReader(“config/res.txt”));

boolean b = false;

while ((string = reader.readLine()) != null)

{

String key = string.substring(0, string.indexOf(‘=’));

String value = string.substring(string.indexOf(‘=’) + 1).trim();

if (key.equals(“destPath”))

{

FatWarMain.destPath = value;

b = true;

}

if (key.equals(“workPath”))

{

FatWarMain.workPath = value;

}

}

if (!b)

{

FatWarMain.destPath = String.valueOf(new Date().getTime());

}

}

catch (IOException e)

{

e.printStackTrace();

}

finally

{

try

{

if (reader != null)

{

reader.close();

}

}

catch (IOException e)

{

e.printStackTrace();

}

}

}

}

———————————————————-

public class Handle

{

/**

* 拷贝文件

* @param source 原文件

* @param dest   目标文件

*/

public static void copyFile(File source, File dest)

{

FileInputStream inputStream = null;

FileOutputStream outputStream = null;

try

{

if (!dest.exists())

{

dest.getParentFile().mkdirs();

}

inputStream = new FileInputStream(source);

outputStream = new FileOutputStream(dest);

byte[] bs = new byte[8192];

int size = 0;

while ((size = inputStream.read(bs)) != -1)

{

outputStream.write(bs, 0, size);

}

outputStream.flush();

}

catch (FileNotFoundException e)

{

e.printStackTrace();

}

catch (IOException e)

{

e.printStackTrace();

}

finally

{

try

{

if (outputStream != null)

{

outputStream.close();

}

}

catch (IOException e)

{

}

try

{

if (inputStream != null)

{

inputStream.close();

}

}

catch (IOException e)

{

}

}

}

}

——————————————————-

# Set root category priority to INFO and its only appender to CONSOLE.

log4j.rootCategory=info, file, stdout

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d [%p] %m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender

# log4j.appender.logfile.MaxBackupIndex=10

# log4j.appender.logfile.MaxFileSize=102400KB

log4j.appender.file.File=log/fatwar.log

log4j.appender.file.append=false

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=%d [%p] %m%n

Linux下载、上传命令

五月 4, 2009 作者:admin  
类别:JAVA开发

linux系统下可以直接从客户端上传文件到服务器端,命令格式:

scp files user@server:filepath

解释:

files 待上传的文件,可以有多个,多个文件之间用空格隔开。也可以用*.filetype上传某个类型的全部文件

user 服务端登录用户名

server 服务器名(IP或域名)

filepath 上传到服务器的目标路径(这里注意此用户一定要有这个路径的读写权限)

 

如果从其它linux系统下载文件到本地可以用:

scp user@server:files client_file_path

解释:

user 服务端登录用户名

server 服务器名(IP或域名)

files 待下载的文件

client_file_path 下载到本地的存放路径

 

linux系统下也可以直接用命令形式从网上下载文件,命令格式:

lftp -c “pget -n 5 http://downpath

解释:

lftp 文件下载命令,通过ftp通道传输

pget -n 5 O也不清楚这里的意义 -_-

http://downpath 待下载文件的连接地址

 

这二个方法的传输速度都比较快,所以记录下来以供参考。

jBPM4中文文档

三月 13, 2009 作者:admin  
类别:JAVA开发

jbpm前段时jBPM4的测试版发布了,大致看了一下,因为时间比较紧没有怎么细看,4版本变化挺大,引入了流程虚拟机的概念。

  看网上朋友翻译了一下用户手册,http://family168.com/tutorial/jbpm4.0/html/index.html,希望对大家有帮助。

Java调用Win exe程序

一月 22, 2009 作者:admin  
类别:JAVA开发

java// 用Java调用windows系统的exe文件,比如notepad,calc之类

Runtime rn = Runtime.getRuntime();

rn.exec(command);

// 2.0调用其他的可执行文件,例如:自己制作的exe,或是下载安装的软件

Runtime rn = Runtime.getRuntime();

rn.exec(“”E:/QQ2008Spring.exe”");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class transferExe {
 
/**
 
* @param args
 
*/
 
public static void main(String[] args) {
 
openWinExe();
 
openMyExe();
 
}
 
// 用Java调用windows系统的exe文件,比如notepad,calc之类
 
public static void openWinExe() {
 
Runtime rn = Runtime.getRuntime();
 
Process p = null;
 
try {
 
String command = "notepad";
 
p = rn.exec(command);
 
} catch (Exception e) {
 
System.out.println("Error win exec ");
 
}
 
}
 
// 2.0调用其他的可执行文件,例如:自己制作的exe,或是下载安装的软件
 
public static void openMyExe() {
 
Runtime rn = Runtime.getRuntime();
 
Process p = null;
 
try {
 
p = rn.exec(""E:/QQ2008Spring.exe"");
 
} catch (Exception e) {
 
System.out.println("Error my exec ");
 
}
 
}
 
}

jBPM 4 Alpha1发布

一月 13, 2009 作者:admin  
类别:JAVA开发

jBPM 4 首个版本Alpha 1发布。BPM业务流程管理和workflow工作流以各种形式存在,jBPM 4向提供一个单一BPM解决方案迈进了一大步,它能够在不同的Java环境中,被不同形式的BPM和workflow使用。jBPM 4能够作为单独的服务器使用或者嵌入任何Java应用。jBPM 4.0.0 Alpha 1是jBPM 4 的首个发布版本,它带来了新的流程虚拟机,支持多个流程语言。jBPM 4最值得注意的改进有:

* 大量改进的文档,包括分开用户使用手册和开发者使用手册
* 基于Eclipse的图形化设计的BPMN
* 基于命令行的服务作为主要的客户端API
* 解耦的行为实现API
* 多种运行模式
* 改进的多语言支持
* 容易添加客户行为
* DB进化改良和DB通过每流程语言划分
BPM and workflow comes in many shapes and forms. jBPM 4 is a major step towards providing a single BPM solution that can be used for these different forms of BPM and workflow, in different Java environments. It can be used as a standalone server or embedded into any Java application. jBPM 4.0.0.Alpha1 is the first release of jBPM 4 and it leverages the new Process Virtual Machine which supports multiple process languages. The most notible improvements in jBPM 4 are:

* Much improved docs, including a split between user guide and developers guide
* BPMN based graphical designer in eclipse
* Command based services as the primary client API
* Decoupled activity implementation API
* Multiple execution modes
* Improved multiple language support
* Easy addition of custom activities
* DB evolution improvements
* DB partitioning per process language

jbpm的调度应用

十二月 6, 2008 作者:admin  
类别:JAVA开发

以前开始接触jbpm的时候,也曾经发表了一篇关于调度的文章http://blog.csdn.net/,其中有很多不甚了解的东东,这几天又研究了一下,共享给各位学友。

阅读全文

彻底解决Dom4j编码问题

八月 5, 2008 作者:admin  
类别:JAVA开发

这几天开始学习dom4j,在网上找了篇文章就开干了,上手非常的快,但是发现了个问题就是无法以UTF-8保存xml文件,保存后再次读出的时候会报“Invalid byte 2 of 2-byte UTF-8 sequence.”这样一个错误,检查发现由dom4j生成的这个文件,在使用可正确处理XML编码的任何的编辑器中中文成乱码,从记事本查看并不会出现乱码会正确显示中文。让我很是头痛。试着使用GBK、gb2312编码来生成的xml文件却可以正常的被解析。因此怀疑的dom4j没有对utf-8编码进行处理。便开始查看dom4j的原代码。终于发现的问题所在,是自己程序的问题。
在dom4j的范例和网上流行的《DOM4J 使用简介》这篇教程中新建一个xml文档的代码都类似如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void createXML(String fileName) {
        Document doc = org.dom4j.DocumentHelper.createDocument();
        Element root = doc.addElement("book");
        root.addAttribute("name", "我的图书");
        Element childTmp;
        childTmp = root.addElement("price");
        childTmp.setText("21.22");
        Element writer = root.addElement("author");
        writer.setText("李四");
        writer.addAttribute("ID", "001");
        try {
            org.dom4j.io.XMLWriter xmlWriter = new org.dom4j.io.XMLWriter(
                    new FileWriter(fileName));
            xmlWriter.write(doc);
            xmlWriter.close();
        }catch (Exception e) {
            System.out.println(e);
        }
    }

在上面的代码中输出使用的是FileWriter对象进行文件的输出。这就是不能正确进行文件编码的原因所在,java中由Writer类继承下来的子类没有提供编码格式处理,所以dom4j也就无法对输出的文件进行正确的格式处理。这时候所保存的文件会以系统的默认编码对文件进行保存,在中文版的 window下java的默认的编码为GBK,也就是所虽然我们标识了要将xml保存为utf-8格式但实际上文件是以GBK格式来保存的,所以这也就是为什么能够我们使用GBK、GB2312编码来生成xml文件能正确的被解析,而以UTF-8格式生成的文件不能被xml解析器所解析的原因。
好了现在我们找到了原因所在了,我们来找解决办法吧。首先我们看看dom4j是如何实现编码处理的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   public XMLWriter(OutputStream out) throws UnsupportedEncodingException {
        //System.out.println("In OutputStream");
        this.format = DEFAULT_FORMAT;
        this.writer = createWriter(out, format.getEncoding());
        this.autoFlush = true;
       namespaceStack.push(Namespace.NO_NAMESPACE);
    }
 
    public XMLWriter(OutputStream out, OutputFormat format) throws                                UnsupportedEncodingException {
        //System.out.println("In OutputStream,OutputFormat");
        this.format = format;
        this.writer = createWriter(out, format.getEncoding());
        this.autoFlush = true;
       namespaceStack.push(Namespace.NO_NAMESPACE);
    }
 
    /**
     * Get an OutputStreamWriter, use preferred encoding.
     */
 
    protected Writer createWriter(OutputStream outStream, String encoding) throws UnsupportedEncodingException {
        return new BufferedWriter(
            new OutputStreamWriter( outStream, encoding )
        );
    }

由上面的代码我们可以看出dom4j对编码并没有进行什么很复杂的处理,完全通过java本身的功能来完成。所以我们在使用dom4j的来生成我们的XML文件时不应该直接为在构建XMLWriter时,不应该直接为其赋一个Writer对象,而应该通过一个OutputStream的子类对象来构建。也就是说在我们上面的代码中,不应该用FileWriter对象来构建xml文档,而应该使用 FileOutputStream对象来构建所以将代码修改入下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    public void createXML(String fileName) {
        Document doc = org.dom4j.DocumentHelper.createDocument();
        Element root = doc.addElement("book");
        root.addAttribute("name", "我的图书");
        Element childTmp;
        childTmp = root.addElement("price");
        childTmp.setText("21.22");
        Element writer = root.addElement("author");
        writer.setText("李四");
        writer.addAttribute("ID", "001");
        try {
            //注意这里的修改
            org.dom4j.io.XMLWriter xmlWriter = new org.dom4j.io.XMLWriter(
                    new FileOutputStream(fileName));
            xmlWriter.write(doc);
            xmlWriter.close();
        }
        catch (Exception e) {
            System.out.println(e);
        }
    }

至此DOM4J的问题编码问题算是告一段落,希望对此文章对其他朋友有用。

理解JBPM的基本概念

七月 15, 2008 作者:admin  
类别:JAVA开发

理解JBPM(java Business Process Management)的基本概念:

jPDL – JBPM Process Definition Language

JBPM简要过程:
1、定义流程(利用JPDL)
2、部署流程(部署到数据库)
3、创建公文并与流程实例绑定
4、可通过JBPM的接口,触发流程向下流动
5、可通过JBPM的接口,获得流动到某个用户那里的文档(即待处理任务列表)
6、可通过JBPM的接口,结束某个用户的任务(这将触发流程继续向下流动)
7、如此,直到结束

———————————————-
测试:

1、安装JBPM
- 引入Hibernate依赖包
- 引入JBPM依赖包
* bsh.jar
* jcr-1.0.jar
* jbpm-identity.jar
* jbpm-jpdl.jar
- 引入数据库驱动
* mysql-connector-java-3.1.13-bin.jar
2、定义相关配置文件
- Hibernate配置文件
* 提供hibernate配置文件(可以从config/目录下拷贝,并修改其中的数据库连接设置即可)
3、假设现在有一个公文,需要经过:张三、李四、王五的审批之后才能结束
4、我们定义一个Document对象,及其hibernate映射,并将修改hibernate配置文件,将映射添加到其配置中(以便创建相应的数据库表)
5、现在让我们来测试一下:
- 创建数据库表: JbpmConfiguration.getInstance().createSchema();
- 定义流程: 参考process.xml
- 部署流程:
* JbpmConfiguration.getInstance() – 创建jbpmConfiguration对象
* ProcessDefinition.parseXmlResource(String); – 读取流程定义文件,创建processdefinition对象
* jbpmConfiguration.createJbpmContext(); – 创建jbpmContext对象
* context.deployProcessDefinition(definition); – 部署流程到数据库
* context.close(); – 关闭context对象
- 创建公文
- 将公文与流程绑定(即需要创建流程实例)
* JbpmConfiguration.getInstance() – 创建jbpmConfiguration对象
* jbpmConfiguration.createJbpmContext(); – 创建jbpmContext对象
* context.setSessionFactory(sessionFactory),将JBPM与程序中的session绑定
* context.getGraphSession().findLatestProcessDefinition(“流程名称”);
* new ProcessInstance(definition); – 创建流程实例
* context.save(processInstance); – 存储流程实例
* 在Document中添加Long processInstanceId 属性
* context.getSession().load 操作,加载Document对象
* document.setProcessInstanceId – 绑定流程实例到公文
* processInstance.getContextInstance.createVariable(“document”,document.getId()) – 绑定公文到流程实例
- 公文创建者提交公文
* (Document)context.getSession().load(Document.class, 1); – 加载公文信息
* context.getProcessInstance(从公文中获取的流程实例ID); – 即根据流程实例ID加载流程实例
* processInstance.getRootToken().signal(); – 触发流程往下走(即到达第一个节点)
- 这时候,我们可以测试一下,看看流程当前所处的节点
* processInstance.getRootToken().getNode().getName()
- 第一个节点对应的用户登录,应该能够查询到其当前的任务(有公文等待其审批)
* List tasks = context.getTaskMgmtSession().findTaskInstances(“张三”); – 查找张三的任务列表
* 列表元素是TaskInstance实例
* 通过:taskInstance.getProcessInstance().getContextInstance().getVariable(“document”); 可以找到其绑定的公文ID
- 查找到当前的任务对应的公文之后,即可对其审批,并继续往下走
* taskInstance.end();
- 如此,直到结束
* processInstance.hasEnded() – 如果流程已经到达终点,本调用将返回true

1个定义文件可以创建一个流程定义的多个版本
一个流程定义可以创建多个流程实例
一个流程实例可以和多个公文绑定
公文与流程的绑定 通过在公文创建一个id字段,把流程的id赋给它

下一页 »