Linux下载、上传命令
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中文文档
前段时jBPM4的测试版发布了,大致看了一下,因为时间比较紧没有怎么细看,4版本变化挺大,引入了流程虚拟机的概念。
看网上朋友翻译了一下用户手册,http://family168.com/tutorial/jbpm4.0/html/index.html,希望对大家有帮助。
Java调用Win exe程序
// 用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发布
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的调度应用
以前开始接触jbpm的时候,也曾经发表了一篇关于调度的文章http://blog.csdn.net/,其中有很多不甚了解的东东,这几天又研究了一下,共享给各位学友。
彻底解决Dom4j编码问题
这几天开始学习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的基本概念
理解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赋给它
jbpm任务分配管理
一个Task instance(任务实例)可以被分配给一个actorId (java.lang.String)。所有的Task instance都被保存在数据库中的表jbpm_taskinstance里。当你想得到特定用户的任务清单时,你就可以通过一个与用户关联的 actorId来查询这张表。
一个流程定义有一个TaskMgmtDefinition;一个TaskMgmtDefinition对应多个swimlane,同时对应多个 task;一个swimlane有多个task,可以 TaskMgmtDefinition中通过task的名称直接获取相应的task;
swimlane对象有四个属性,分别是name(名字)、assignmentDelegation(分配代理类)、taskMgmtDefinition、tasks(Set 对应多个task),可以增加task
task对象主要的属性:taskMgmtDefinition、swimlane、assignmentDelegation、 taskNode,需要注意的是swimlane和assignmentDelegation中间只是可以一个属性有值,因为它们都和任务的分配有关系。
一个流程实例有一个TaskMgmtInstance;一个TaskMgmtInstance对应多个swimlaneInstance,同时对应多个taskInstance;一个swimlaneInstance有多个taskInstance,可以从TaskMgmtInstance中直接获取相应的taskInstance;
swimlaneInstance对象主要有五个属性,分别是name、actorId、pooledActors(Set)、swimlane、taskMgmtInstance。
taskInstance对象的主要属性:name、actorId、task、swimlaneInstance、taskMgmtInstance、pooledActors。
当对任务进行分配时,一般需要实现AssignmentHandler这个接口,这个接口的方法只有一个:
void assign( Assignable assignable, ExecutionContext executionContext ) throws Exception;
一个典型的实现(把名字是’change nappy’的任务交给NappyAssignmentHandler这个类来分配)
<task name=’change nappy’>
<assignment class=’org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler’ />
</task>
NappyAssignmentHandler类:
public void assign(Assignable assignable, ExecutionContext executionContext) {
assignable.setActorId(”papa”);
}
同样,Assignable只是一个接口,它有两个方法:setActorId()和setPooledActors(),Assignable的具体实现类也是两个
swimlaneInstancehe和taskInstance。这样就不不难理解整个任务分配流程了:
1、流程进入TaskNode节点,执行TaskNode类的execute()方法,该方法首先获得TaskMgmtInstance实例,然后通过它来创建TaskInstance。taskMgmtInstance.createTaskInstance(task, executionContext);
2、在上面的createTaskInstance(task, executionContext)里,该方法调用了taskInstance.assign(executionContext)对taskInstance进行分配。
3、在assign(executionContext)方法里,首先会判断task属性里是否存在swimlane,如果有的话,这个 taskInstance就会分配给swimlane指定的ActorId或 PooledActors;如果不存在,再去找task属性里 assignmentDelegation(分配代理类)通过代理类(即我们自己写的实现AssignmentHandler这个接口的类)指定 ActorId或 PooledActors。

