增加ModelDriven支持
publicabstract class BaseActionWithModelDriven<T>extends BaseAction implements ModelDriven<T> {
////////////////////////ModelDriven支持////////////
protected T model = null;
public BaseActionWithModelDriven(){
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
Class<T> clazz = (Class<T>)pt.getActualTypeArguments()[0];
try {
model = clazz.newInstance();
} catch (Exception e) {
thrownew RuntimeException(e);
}
}
public T getModel() {
returnmodel;
}
}
Service中因为我们不能直接增删改jbpm的数据,所以并不需要继承DaoSupport
@Service
@Transactional
publicclass ProcessDefinitionServiceImpl implements ProcessDefinitionService {
@Resource
private ProcessEngine processEngine;
查询最新的所有流程定义
public List<ProcessDefinition> findAllLatestVersions() {
// 1,查询所有的流程定义列表,把最新的版本都排到最后面
List<ProcessDefinition> all = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//
.list();
// 2,过滤出所有最新的版本
Map<String, ProcessDefinition> map = new HashMap<String,ProcessDefinition>();
for (ProcessDefinition pd : all) {
map.put(pd.getKey(), pd);
}
returnnew ArrayList<ProcessDefinition>(map.values());
}
根据key删除所有
/** 删除 */
public String delete() throws Exception {
// key = newString(key.getBytes("iso8859-1"), "utf-8");
key = URLDecoder.decode(key, "utf-8"); // 自己再进行一次URL解码
processDefinitionService.deleteByKey(key);
return"toList";
}
publicvoid deleteByKey(String key) {
// 1,查询出指定key的所有版本的流程定义
List<ProcessDefinition> list = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.processDefinitionKey(key)//
.list();
// 2,循环删除
for (ProcessDefinition pd : list) {
processEngine.getRepositoryService().deleteDeploymentCascade(pd.getDeploymentId());
}
}
部署流程定义
/** 部署 */
public String add() throws Exception {
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(upload));//upload是上传来的文件
try {
processDefinitionService.deploy(zipInputStream);
} finally {
zipInputStream.close();
}
return"toList";
}
publicvoid deploy(ZipInputStream zipInputStream) {
processEngine.getRepositoryService()//
.createDeployment()//
.addResourcesFromZipInputStream(zipInputStream)//
.deploy();
}
/** 查看流程图,其实是下载功能 */
public String downloadProcessImage() throws Exception {
//用于流程图查看提供的流程定义ID
id = URLDecoder.decode(id, "utf-8"); // 自己再进行一次URL解码
inputStream = //根据下载的配置要求提供一个流
processDefinitionService.getProcessImageResourceAsStream(id);
return"downloadProcessImage";
}
public InputStream getProcessImageResourceAsStream(StringprocessDefinitionId) {
// 根据id取出对应的流程定义对象
ProcessDefinition pd = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
.processDefinitionId(processDefinitionId)//
.uniqueResult();
// 返回图片资源
returnprocessEngine.getRepositoryService().getResourceAsStream(pd.getDeploymentId(),pd.getImageResourceName());
}
JSP页面中写的js代码传递参数的时候注意,如果是字符串必须加上单引号,因为EL表达式在服务端执行,解析后如果没加单引号就形成如下,这样显然执行会出错
<ahref="javascript: showProcessImage(${id})">查看流程图</a>
<ahref="javascript:showProcessImage(hjdf)">查看流程图</a>
修改成如下之后就能正确执行了
<ahref="javascript:showProcessImage('${id}')">查看流程图</a>
<ahref="javascript:showProcessImage('hjdf')">查看流程图</a>
打开新窗口显示图片
<scripttype="text/javascript">
functionshowProcessImage( pdId ){
// alert("原文:" + pdId);
pdId = encodeURI(pdId);
// alert("第一次URL编码:" + pdId);
pdId = encodeURI(pdId);
// alert("第二次URL编码:" + pdId);
var url ="processDefinitionAction_downloadProcessImage.action?id=" + pdId +"&t=" + new Date();//对于这种js提交的请求最好加上时间戳,防止不刷新
window.showModalDialog(url,null,"dialogHeight:500px;dialogWidth:600px;resizable:yes");
}
</script>
<s:formaction="processDefinitionAction_add"enctype="multipart/form-data">//默认就是post
而<form>默认是get请求
<s:aaction="processDefinition_delete"onclick="return delConfirm()">
<s:paramname="key"value="%{@java.net.URLEncoder@encode(key, 'utf-8')}"></s:param>
删除
</s:a>
像上面这种在OGNL中调用了静态方法,必须在struts.xml中配置
<!-- 让OGNL中可以使用静态的方法 -->
<constantname="struts.ognl.allowStaticMethodAccess"value="true"/>
限制选择的文件的扩展名,详细的使用见jQuery-validator的文档
<inputtype="file"name="upload"class="InputStyle {required:true,accept:'.zip'}"style="width:450px;"/>
乱码问题的解决
表单采用Post方式提交,解决乱码的方法为:
request.setCharacterEncoding( myEncoding );
表单采用Get方式提交,解决乱码的方法为:
方式一:
key = newString(key.getBytes("iso8859-1"), "utf-8");
方式二:
修改server.xml: URIEncoding="utf-8"
方式三(不依赖Tomcat的配置,那么你的信息必须是英文的,通过转换嘛。推荐
另外Base64的思想,都可以把二进制转换成字符):
浏览器中两次URL编码。
服务器中自己再做一次URL解码。
<s:param自己本身有一次编码
<s:aaction="processDefinitionAction_delete" onclick="returndelConfirm()">
<s:param name="key" value="%{@java.net.URLEncoder@encode(key,'utf-8')}"></s:param>
删除
</s:a>
/**
* 保存上传的文件,并返回文件在服务端的真实存储路径
*
* @param upload
* @return
*/
protected String saveUploadFile(File upload) {
SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
// >>获取路径
String basePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/upload_files");
String subPath = sdf.format(new Date());
// >>如果文件夹不存在,就创建
File dir = new File(basePath + subPath);
if (!dir.exists()) {
dir.mkdirs(); // 递归的创建不存在的文件夹
}
// >>拼接路径
String path = basePath + subPath + UUID.randomUUID().toString();
// >>移动文件
upload.renameTo(new File(path));// 如果目标文件夹不存在,或是目标文件已存在,就会不成功,返回false,但不报错。
return path;
}
<!-- 下载专用的结果配置 -->
<resultname="download"type="stream">
<paramname="contentType">application/octet-stream</param>
<paramname="inputName">inputStream</param>
<paramname="contentDisposition">attachment;filename="${#fileName}.doc"</param>
</result>
/** 下载 */
public String download()throws Exception {
//准备下载的资源
ApplicationTemplate applicationTemplate =applicationTemplateService.getById(model.getId());
inputStream =new FileInputStream(applicationTemplate.getPath());
//准备文件名(解决乱码问题)
String fileName = URLEncoder.encode(applicationTemplate.getName(),"utf-8");// 方法一
// String fileName = newString(applicationTemplate.getName().getBytes("gbk"),"iso8859-1"); //方法二
ActionContext.getContext().put("fileName", fileName);
return"download";
}
// ---
public InputStream getInputStream() {
returninputStream;
}
// 服务器端的文件存储方案:
方案一:存到数据库中(BLOB)。
方案二:存到服务器的某文件夹中(推荐)。
需要String型的path(相对于服务器的一个相对路径)。
问题:
文件重名:使用UUID做为文件名,如果需要原始的文件名,则可以存到数据库中(用一个列)。
文件过多:分文件夹存放