传智播客学习笔记6.4

来源:互联网 发布:手机淘宝上传图片尺寸 编辑:程序博客网 时间:2024/06/04 18:18

传智播客学习笔记6.4

错误时如何回显页面?

1/addUI中重新准备数据

2、单独写一个回显的action?(待试验)

使用两层架构:view + service(service+dao)
使用技术:struts1 + jstl1.1 + hibernate + jbpm

要完成的功能:
 组织与人员管理
 流程管理: 部署,删除,查看流程图片,查看流程定义文件,备份
 流程监控: 用图形显示当前正在执行的节点。
 流程: 请假的(审批)流程。

常见的是审批流程, 如经常提到的请假与报销等. 还有一些其它流程, 如开会的
流程为: 准备议题 --> 选择与会人员 --> 会议通知 --> 会议纪要 --> 发送会
议纪要给与会人员.

* 一、准备环境:
1,创建目录结构:
    源码文件夹:src/java,src/process,src/config,test/java;
 文档资料文件夹doc;
2,添加所使用的框架的环境:
   a) 添加jar包:
      struts(使用MyEclipse添加,这样他可以配置好配置文件);
   jstl1.1;
   jbpm3.2.2的jar包(包含了Hibernate3.2.3);
      相应的jdbc驱动;
   b) 添加配置文件:
      jbpm.cfg.xml
      hibernate.cfg.xml
      log4j.properties
   c) 解决struts1.2.9中的commons-beanutils.jar与hibernate3.2中的
      commons-collections.jar版本不匹配问题。
3,创建所用的数据库,修改hibernate.cfg.xml中的数据库连接信息,并生成相
   应的数据库表。

* 二、部门人员职务管理
主要完成部门人员职务等基础模块中的增删改查。

1,设计部门人员职务的实体:Department, User, Role. 并要求练习:1,搭建
   环境。2,写映射文件并生成相应的数据库表。
2,分析部门有关的功能要求与显示页面,和表单的验证要求。然后由学员在自己
   的工程中实现部门模块的功能。要做的工作有:1,使用view+serivce架构,
   即在service 中直接使用Session;2,使用过滤器控制事务;3,完成分析的
   部门有关的功能。
3,控制事务时实现,如果当前请求中没有用到session,就不会创建session和开
   始事务,是通过ThreadLocal配合实现的。这时要注意在web容器中有一个线程
   池的机制,就是说两次请求有可能是使用的同一个线程,这样就会出现第二次
   请求使用的是第一次请求中已关闭的session,就会抛异常。可以在判断的时
   候把条件改为当((session == null || !session.isOpen()) && create)成立
   时才创建新的Session; 还要注意,在关闭session时一定要把当前线程对应
   的session置为null。否则,后面使用同一个线程(此次请求中没有调用方法
   getSession(true))的请求就有可能使用这个已关闭的session。如果在过滤
   器中的chain.doFilter中没有用到session,因为getSession方法中的判断,
   在chain.doFilter代码后的getSession(false)就可能会返回上一次请求(同
   一个线程)中关闭的session。

4,使用xtree显示部门列表,可以参照以下步骤练习:
   a) xTree的使用(通过js);
   b) 递归显示部门与其子部门的信息;
   c) 在Java中通过递归拼接出要在js中使用的显示tree的代码,要有正确的结构;

5,快速完成Role的管理(增删改查)。快速完成User的管理(增删改查),其中
   添加人员时选择部门和多选职务与他们的错误回显。
6,人员添加或修改验证失败后不能再返回到页面(jsp),而应返回到xxUI(addUI
   或editUI),这样就能再次准备数据。这样会引出一个新的问题,就是xxUI中
   会再次准备formbean 的数据,导致表单页面中不能显示上次的错误输入,而
   是显示原始信息。解决办法是在xxUI中准备formbean数据时加一个条件:只有
   不是验证失败后转过来的请求 才准备formbean的数据。而这个判断可以使用
   一个第一次转到表单页面中没有,验证失败后转过的请求中有的参数的值,如:
   if(actionForm.name==null){不是验证失败转过来的,应准备formbean数据}。


* 三、流程定义管理

要完成的功能:
1,流程定义列表:默认显示所有流程定义的最后一个版本;还可以显示指定的流
   程定义的所有版本。
2,部署流程定义(PAR):使用文件上传,部署流程定义文档。
3,流程定义文件查看:在线查看流程定定文件(processdefinition.xml)。
4,流程图片查看:在线查看流程图片(processsimage.jpg)。
5,备份流程定义:把流程定义文档打包(zip)下载;要求默认的名字格式为:
   "${流程定义名称}_${流程定义的版本}"。
6,删除流程定义。

** 准备知识:

*** 1,将要使用到的API:
a) 查询所有流程定义的最后一个版本:
   JbpmContext.getGraphSession().findLatestProcessDefinitions();
b) 查询指定名称的流程定义的所有版本:
   JbpmContext.getGraphSession().findAllProcessDefinitionVersions(String);
c) 解析流程定义档:
   ProcessDefinition.parseParZipInputStream(zipInputStream);
d) 部署流程定义:
   JbpmContext.getGraphSession().deployProcessDefinition(pd);
e) 从流程定义中获取原流程定义文档中的文件:
// 相对于流程定义文档(zip包中)的根目录的相对文件路径,如 classes/cn/itcast/Test.class
   String filePath;
// 方法一
   // 获取指定文件的文件内容
   byte[] fileContent = pd.getFileDefinition().getBytes(fileName);
   // 获取所有文件的内容,Map的key是文件路径,value是文件内容
   Map<String, byte[]> files = pd.getFileDefinition().getBytesMap();
// 方法二
   // 获取指定文件的内容的输入流
   InputStream inStream = pd.getFileDefinition().getInputStream(fileName);
   // 获取所有文件的内容的输入流,Map的key文件路径,value是文件内容的输入流
   pd.getFileDefinition().getInputStreamMap();
f) 删除流程定义:
   JbpmContext.getGraphSession().deleteProcessDefinition(id);

*** 2,其他相关知识:
a) 向浏览器输出jpg图片时,设置 ContextType 为 image/jpeg;
   输出xml时,设置 contentType 为 text/xml; charset=编码;
   下载文件时,设置 ContentType 为 application/zip,并且增加头信息:
     Content-Disposition = attachment; filename=文件名(进行URL编码)
b) 用java写zip文件,示例代码如下:
   ZipOutputStream out = new ZipOutputStream(outputStream);
   out.putNextEntry(new ZipEntry(fileName)); // 添加一项
   out.write(file11);
   out.closeEntry();
   // ... 写其他文件或文件夹项
   out.close(); // 写完后一定调用close()方法

   1,ZipEntry可以代表一个文件或是一个文件夹,当name以'/'结尾时代表一个
   文件夹。  ZipEntry的name是指的一个相对路径(相对于zip包中的根目录)。
   例如想在zip文件中的"dir"目录下有一个文件a.txt,可以写成"dir/a.txt";
   如果想在dir1下有一个dir2文件夹,应写为"dir1/dir2/"(以'/'结尾),最
   终会递归的创建这个目录结构,即不要求dir2以上的目录是存在的。

   2,在调用ZipOutputStream的putNextEntry(ZipEntry)方法或close()方法后,
   会自动关闭上一个未关闭的ZipEntry(所以可以不必显示调用closeEntry()方
   法)。
  
   3,写完zip后一定要调用ZipOutputStream.close()方法,否则会造成写出的
   zip文件不完整。

   4,在压缩文件时如果zip中有中文名的文件,就会变成乱码。这是由于jdk
   (使用有版本为5.0)中把ZipEntry的名字硬编码使用utf-8编码再写到zip中,
   而我们windows的本地编码为gbk,用gbk显示时就变成了乱码。 由于是硬编码,
   所以不能修改,但我们可以使用ant包中的ZipOutputStream与ZipEntry,使用
   代码不用改,就可以解决压缩时的中文乱码了。


汤老师编写代码的经验相当丰富。