activiti学习由浅入深03 weir 2014-12-26 11:11:43.0 java,activiti 909 我先把 请假流程.bpmn 文件的内容拿出来: <?xml version=”1.0″ encoding=”UTF-8″?> <definitions xmlns=”http://www.omg.org/spec/BPMN/20100524/MODEL” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:activiti=”http://activiti.org/bpmn” xmlns:bpmndi=”http://www.omg.org/spec/BPMN/20100524/DI” xmlns:omgdc=”http://www.omg.org/spec/DD/20100524/DC” xmlns:omgdi=”http://www.omg.org/spec/DD/20100524/DI” typeLanguage=”http://www.w3.org/2001/XMLSchema” expressionLanguage=”http://www.w3.org/1999/XPath” targetNamespace=”http://www.activiti.org/test”> <process id=”leave” name=”请假流程” isExecutable=”true”> <startEvent id=”startevent” name=”开始” activiti:initiator=”applyuser”></startEvent> <userTask id=”depLeaderAduit” name=”部门领导审批” activiti:candidateUsers=”1000″></userTask> <sequenceFlow id=”flow1″ sourceRef=”startevent” targetRef=”depLeaderAduit”></sequenceFlow> <exclusiveGateway id=”exclusivegateway1″ name=”Exclusive Gateway”></exclusiveGateway> <sequenceFlow id=”flow2″ sourceRef=”depLeaderAduit” targetRef=”exclusivegateway1″></sequenceFlow> <userTask id=”hrLeaderAduit” name=”人事资源审批” activiti:candidateUsers=”1000,1001″></userTask> <userTask id=”usertask1″ name=”调整申请” activiti:assignee=”${applyuser}”></userTask> <sequenceFlow id=”flow3″ name=”同意” sourceRef=”exclusivegateway1″ targetRef=”hrLeaderAduit”> <conditionExpression xsi:type=”tFormalExpression”><![CDATA[${departLeaderPass}]]></conditionExpression> </sequenceFlow> <sequenceFlow id=”flow4″ name=”不同意” sourceRef=”exclusivegateway1″ targetRef=”usertask1″> <conditionExpression xsi:type=”tFormalExpression”><![CDATA[${!departLeaderPass}]]></conditionExpression> </sequenceFlow> <exclusiveGateway id=”exclusivegateway2″ name=”Exclusive Gateway”></exclusiveGateway> <sequenceFlow id=”flow5″ sourceRef=”usertask1″ targetRef=”exclusivegateway2″></sequenceFlow> <sequenceFlow id=”flow6″ sourceRef=”exclusivegateway2″ targetRef=”depLeaderAduit”></sequenceFlow> <exclusiveGateway id=”exclusivegateway3″ name=”Exclusive Gateway”></exclusiveGateway> <sequenceFlow id=”flow7″ sourceRef=”hrLeaderAduit” targetRef=”exclusivegateway3″></sequenceFlow> <userTask id=”usertask2″ name=”销假” activiti:assignee=”${applyuser}”></userTask> <sequenceFlow id=”flow8″ name=”同意” sourceRef=”exclusivegateway3″ targetRef=”usertask2″> <conditionExpression xsi:type=”tFormalExpression”><![CDATA[${hrLeaderPass}]]></conditionExpression> </sequenceFlow> <sequenceFlow id=”flow9″ name=”不同意” sourceRef=”exclusivegateway3″ targetRef=”usertask1″> <conditionExpression xsi:type=”tFormalExpression”><![CDATA[${!hrLeaderPass}]]></conditionExpression> </sequenceFlow> <exclusiveGateway id=”exclusivegateway4″ name=”Exclusive Gateway”></exclusiveGateway> <sequenceFlow id=”flow10″ sourceRef=”usertask2″ targetRef=”exclusivegateway4″></sequenceFlow> <serviceTask id=”mailtask1″ name=”Mail Task” activiti:type=”mail”> <extensionElements> <activiti:field name=”subject”> <activiti:string><![CDATA[请假流程回执单]]></activiti:string> </activiti:field> <activiti:field name=”to”> <activiti:expression>${to}</activiti:expression> </activiti:field> <activiti:field name=”from”> <activiti:expression>${form}</activiti:expression> </activiti:field> <activiti:field name=”charset”> <activiti:string><![CDATA[utf8]]></activiti:string> </activiti:field> <activiti:field name=”html”> <activiti:expression>${applyuser},您好,您的请假已处理完毕</activiti:expression> </activiti:field> </extensionElements> </serviceTask> <endEvent id=”endevent1″ name=”结束”></endEvent> <sequenceFlow id=”flow11″ name=”是” sourceRef=”exclusivegateway4″ targetRef=”mailtask1″> <conditionExpression xsi:type=”tFormalExpression”><![CDATA[${need}]]></conditionExpression> </sequenceFlow> <sequenceFlow id=”flow12″ name=”否” sourceRef=”exclusivegateway4″ targetRef=”endevent1″> <conditionExpression xsi:type=”tFormalExpression”><![CDATA[${!need}]]></conditionExpression> </sequenceFlow> </process> <bpmndi:BPMNDiagram id=”BPMNDiagram_leave”> <bpmndi:BPMNPlane bpmnElement=”leave” id=”BPMNPlane_leave”> <bpmndi:BPMNShape bpmnElement=”startevent” id=”BPMNShape_startevent”> <omgdc:Bounds height=”35.0″ width=”35.0″ x=”40.0″ y=”144.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”depLeaderAduit” id=”BPMNShape_depLeaderAduit”> <omgdc:Bounds height=”55.0″ width=”105.0″ x=”110.0″ y=”135.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”exclusivegateway1″ id=”BPMNShape_exclusivegateway1″> <omgdc:Bounds height=”40.0″ width=”40.0″ x=”260.0″ y=”142.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”hrLeaderAduit” id=”BPMNShape_hrLeaderAduit”> <omgdc:Bounds height=”55.0″ width=”105.0″ x=”368.0″ y=”135.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”usertask1″ id=”BPMNShape_usertask1″> <omgdc:Bounds height=”55.0″ width=”105.0″ x=”228.0″ y=”262.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”exclusivegateway2″ id=”BPMNShape_exclusivegateway2″> <omgdc:Bounds height=”40.0″ width=”40.0″ x=”142.0″ y=”269.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”exclusivegateway3″ id=”BPMNShape_exclusivegateway3″> <omgdc:Bounds height=”40.0″ width=”40.0″ x=”400.0″ y=”269.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”usertask2″ id=”BPMNShape_usertask2″> <omgdc:Bounds height=”55.0″ width=”105.0″ x=”497.0″ y=”262.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”exclusivegateway4″ id=”BPMNShape_exclusivegateway4″> <omgdc:Bounds height=”40.0″ width=”40.0″ x=”529.0″ y=”169.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”mailtask1″ id=”BPMNShape_mailtask1″> <omgdc:Bounds height=”55.0″ width=”105.0″ x=”497.0″ y=”80.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement=”endevent1″ id=”BPMNShape_endevent1″> <omgdc:Bounds height=”35.0″ width=”35.0″ x=”640.0″ y=”172.0″></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement=”flow1″ id=”BPMNEdge_flow1″> <omgdi:waypoint x=”75.0″ y=”161.0″></omgdi:waypoint> <omgdi:waypoint x=”110.0″ y=”162.0″></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow2″ id=”BPMNEdge_flow2″> <omgdi:waypoint x=”215.0″ y=”162.0″></omgdi:waypoint> <omgdi:waypoint x=”260.0″ y=”162.0″></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow3″ id=”BPMNEdge_flow3″> <omgdi:waypoint x=”300.0″ y=”162.0″></omgdi:waypoint> <omgdi:waypoint x=”368.0″ y=”162.0″></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height=”14.0″ width=”24.0″ x=”310.0″ y=”162.0″></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow4″ id=”BPMNEdge_flow4″> <omgdi:waypoint x=”280.0″ y=”182.0″></omgdi:waypoint> <omgdi:waypoint x=”280.0″ y=”247.0″></omgdi:waypoint> <omgdi:waypoint x=”280.0″ y=”262.0″></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height=”14.0″ width=”36.0″ x=”290.0″ y=”182.0″></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow5″ id=”BPMNEdge_flow5″> <omgdi:waypoint x=”228.0″ y=”289.0″></omgdi:waypoint> <omgdi:waypoint x=”182.0″ y=”289.0″></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow6″ id=”BPMNEdge_flow6″> <omgdi:waypoint x=”162.0″ y=”269.0″></omgdi:waypoint> <omgdi:waypoint x=”162.0″ y=”190.0″></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow7″ id=”BPMNEdge_flow7″> <omgdi:waypoint x=”420.0″ y=”190.0″></omgdi:waypoint> <omgdi:waypoint x=”420.0″ y=”269.0″></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow8″ id=”BPMNEdge_flow8″> <omgdi:waypoint x=”440.0″ y=”289.0″></omgdi:waypoint> <omgdi:waypoint x=”497.0″ y=”289.0″></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height=”14.0″ width=”24.0″ x=”450.0″ y=”289.0″></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow9″ id=”BPMNEdge_flow9″> <omgdi:waypoint x=”400.0″ y=”289.0″></omgdi:waypoint> <omgdi:waypoint x=”333.0″ y=”289.0″></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height=”14.0″ width=”36.0″ x=”361.0″ y=”312.0″></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow10″ id=”BPMNEdge_flow10″> <omgdi:waypoint x=”549.0″ y=”262.0″></omgdi:waypoint> <omgdi:waypoint x=”549.0″ y=”209.0″></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow11″ id=”BPMNEdge_flow11″> <omgdi:waypoint x=”549.0″ y=”169.0″></omgdi:waypoint> <omgdi:waypoint x=”549.0″ y=”135.0″></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height=”14.0″ width=”12.0″ x=”559.0″ y=”169.0″></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement=”flow12″ id=”BPMNEdge_flow12″> <omgdi:waypoint x=”569.0″ y=”189.0″></omgdi:waypoint> <omgdi:waypoint x=”640.0″ y=”189.0″></omgdi:waypoint> <bpmndi:BPMNLabel> <omgdc:Bounds height=”14.0″ width=”12.0″ x=”579.0″ y=”189.0″></omgdc:Bounds> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions> 各位完全不必要担心自己看不懂这些东西,稍安勿躁,你只需把它复制到你的上面就OK了。 你会看到它可以变成这样,当你再去点击每个图形时你似乎看懂了一点点,好的尽量去理解它,我现在不准备解释什么,我们去做另一件事情,将其生成一个图片,看图: 这时候你就有了两个文件:请假流程.bpmn和请假流程.png 我们要干嘛呢,我们要上传并部署这个流程,你似乎觉得有些疯狂,我还不会画图呢,哦朋友们不要着急,你会有答案的。 我还是想把程序拿出来: /** * 上传并部署 * @param uploadfile * @param session * @return * @throws IOException */ @RequestMapping(“/upload”) public String upload(@RequestParam MultipartFile uploadfile,HttpSession session) throws IOException { if (!uploadfile.isEmpty()) { String realPath = session.getServletContext().getRealPath(“/uploadfile”); byte[] data = uploadfile.getBytes(); File out = new File(realPath, uploadfile.getOriginalFilename()); FileUtils.writeByteArrayToFile(out, data); if(FilenameUtils.getExtension(uploadfile.getOriginalFilename()).equals(“zip”) || FilenameUtils.getExtension(uploadfile.getOriginalFilename()).equals(“bar”)) { ZipInputStream zip = newZipInputStream(uploadfile.getInputStream()); //部署 //添加数据表有act_re_deployment(部署信息表),act_re_procdef(流程定义),act_ge_bytearray(部署信息资源表) repositoryService.createDeployment().name(uploadfile.getOriginalFilename()).addZipInputStream(zip).deploy(); } } return “”; } 看着程序你会发现我们要上传的是压缩文件,对就是把那两个文件压缩在一起,如果你看了用户手册你会发现有很多上传的方法这只是其中的一种,你可以看着用户手册举一反三了。 至于你的系统怎么完成这一步你也可以按照自己的处理方法办,总之要把画好的流程图上传到数据库里面,这时候涉及到的数据库表我也列出来了: act_re_deployment(部署信息表) act_re_procdef(流程定义) act_ge_bytearray(部署信息资源表) 这里要注意的是:如果你用360好压或rar或7-zip 来压缩文件记着文件名不能有中文 如果你想使用中文名,我给你个好东西: package com.weir.test; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipOutputStream; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.zip.ZipEntry; public class ZipUtil { private static final String ENCODE = “UTF-8″; public static void zip(String inputFilePath, String zipFileName) { File inputFile = new File(inputFilePath); if (!inputFile.exists()) throw new RuntimeException(“原始文件不存在!!!”); File basetarZipFile = new File(zipFileName).getParentFile(); if (!basetarZipFile.exists() && !basetarZipFile.mkdirs()) throw new RuntimeException(“目标文件无法创建!!!”); BufferedOutputStream bos = null; FileOutputStream out = null; ZipOutputStream zOut = null; try { // 创建文件输出对象out,提示:注意中文支持 out = new FileOutputStream(new String(zipFileName.getBytes(ENCODE))); bos = new BufferedOutputStream(out); // 將文件輸出ZIP输出流接起来 zOut = new ZipOutputStream(bos); zip(zOut, inputFile, inputFile.getName()); CloseIoUtil.closeAll(zOut, bos, out); } catch (Exception e) { e.printStackTrace(); } } private static void zip(ZipOutputStream zOut, File file, String base) { try { // 如果文件句柄是目录 if (file.isDirectory()) { // 获取目录下的文件 File[] listFiles = file.listFiles(); // 建立ZIP条目 //zOut.putNextEntry(new ZipEntry(base + “/”)); //base = (base.length() == 0 ? “” : base + “/”); if (listFiles != null && listFiles.length > 0) // 遍历目录下文件 for (File f : listFiles) // 递归进入本方法 zip(zOut, f, f.getName()); } // 如果文件句柄是文件 else { if (base == “”) { base = file.getName(); } // 填入文件句柄 zOut.putNextEntry(new ZipEntry(base)); // 开始压缩 // 从文件入流读,写入ZIP 出流 writeFile(zOut, file); } } catch (Exception e) { e.printStackTrace(); } } private static void writeFile(ZipOutputStream zOut, File file) throws IOException { FileInputStream in = null; BufferedInputStream bis = null; in = new FileInputStream(file); bis = new BufferedInputStream(in); int len = 0; byte[] buff = new byte[2048]; while ((len = bis.read(buff)) != -1) zOut.write(buff, 0, len); zOut.flush(); CloseIoUtil.closeAll(bis, in); } /**** * 解压 * * @param zipPath * zip文件路径 * @param destinationPath * 解压的目的地点 * @param ecode * 文件名的编码字符集 */ public static void unZip(String zipPath, String destinationPath) { File zipFile = new File(zipPath); if (!zipFile.exists()) throw new RuntimeException(“zip file ” + zipPath + ” does not exist.”); Project proj = new Project(); Expand expand = new Expand(); expand.setProject(proj); expand.setTaskType(“unzip”); expand.setTaskName(“unzip”); expand.setSrc(zipFile); expand.setDest(new File(destinationPath)); expand.setEncoding(ENCODE); expand.execute(); System.out.println(“unzip done!!!”); } public static void main(String[] args) { String dir = new String(“E:\\zip”); // dir = new String(“C:\\Users\\Administrator\\Desktop\\zip\\请假流程.png”); // zip(dir, “C:/Users/Administrator/Desktop/zip01/请假流程.zip”); zip(dir, “E:/zip/请假流程.zip”); // unZip(“f:/BZBXB/zipant.zip”, “f:/XX/xx/”); } } 利用这个小程序来压缩文件,不管你的文件名是否是中文都可以上传部署。 上传部署完之后我们看看那三张表里面发生了什么: 我们再回过头来看我之前拿出来的xml文件,我截取了一小段: targetNamespace=”http://www.activiti.org/test”> 我们去对照act_re_procdef(流程定义)category_、name_、key_ 等大家应该很明白了吧。 这里大家消化消化,图文并茂的更容易理解,然后再用自己的方式消化它。