关于使用struts2发布JBPM的流程定义

来源:互联网 发布:诺基亚e7软件下载 编辑:程序博客网 时间:2024/06/06 06:35

使用struts2发布JBPM的流程定义也就是用WEB方法发布jbpm流程

有两种方法:

1.使用文件上传的方法:(优点)可以使用任何位置下的XML文件。缺点是必须增加JAR包

我用的是commons-fileupload-1.1.jar和commons-io-1.1.jar。

由于在parseRequest(request)的类有关继承于DiskFileItem
类。而他有private  org.apache.commons.io.output.DeferredFileOutputStream dfos。这样的就必须使用到commons-io-1.1-dev.jar。因此需要导入该包。否则就出classNotFound:.DeferredFileOutputStream的错误。

补充说明:commons-fileupload-1.1.jar和commons-fileupload-1.0.jar的区别,本人只是会抛出异常

java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]

这里特地反驳一下http://blog.csdn.net/ying1979/archive/2007/09/18/1788931.aspx的作者

最近在struts2用到 FCKeditor,在上传图片时总是出错。
严重: Servlet.service() for servlet SimpleUploader threw exception
java.lang.RuntimeException: Unable to load bean org.apache.struts2.dispatcher.multipart.MultiPartRequest (jakarta) - [unknown location]
在网上找了一下,发现
http://bbs.laoer.com/read-topic-6-ff808081143476140114df232a1f2608-0-1-index-1.html
和我的情况差不多。
跟踪了一下源代码,发现struts2的filter拦截了上传文件的动作,
//org.apache.struts2.dispatcher.Dispatcher.java
public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException {
        // don't wrap more than once
        if (request instanceof StrutsRequestWrapper) {
            return request;
        }
        String content_type = request.getContentType();
        if (content_type != null && content_type.indexOf("multipart/form-data") != -1) {
            MultiPartRequest multi = getContainer().getInstance(MultiPartRequest.class);
            request = new MultiPartRequestWrapper(multi, request, getSaveDir(servletContext));
        } else {
            request = new StrutsRequestWrapper(request);
        }
        return request;
    }
在这里又找不到MultiPartRequest.class的实现类。于是出错了。
只要不让struts2拦截处理上传事件,就应该没问题了。
修改web.xml,把原来的
<filter-mapping>
  <filter-name>struts</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
改为
<filter-mapping>
  <filter-name>struts</filter-name>
  <url-pattern>*.action</url-pattern>
 </filter-mapping>
而上传页面调用时直接用文件名调用(如upload.jsp)。struts2只处理 *.action 的请求。
试了一下。和预想的一样,一切OK。

其实解决上诉的方法最快的是。。保持原有配置不变直接升级包。。就可以了。。

而且  <url-pattern>*.action</url-pattern>会带来更多的问题

所以。。建设使用高版本的JAR

 

同时这里涉及到以下两个小知识:

文件上传的原理:

表单元素的enctype属性指定的是表单数据的编码方式,该属性有3个值:
1)      application/x-www-form-urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式。
2)      multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里。
3)      text/plain:这种方式主要适用于直接通过表单发送邮件的方式。
文件上传是web应用经常用到的一个知识。原理是,通过为表单元素设置enctype=”multipart/form-data”属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。
Java领域中,有两个常用的文件上传项目:一个是Apache组织JakartaCommon-FileUpload组件(http://commons.apache.org/fileupload/),另一个是Oreilly组织的COS框架(http://www.servlets.com/cos/)。利用这两个框架都能很方便的实现文件的上传。

 

Struts2并未提供自己的请求解析器,也就是就Struts2不会自己去处理multipart/form-data的请求,它需要调用其他请求解析器,将HTTP请求中的表单域解析出来。但Struts2在原有的上传解析器基础上做了进一步封装,更进一步简化了文件上传。
Struts2默认使用的是JakartaCommon-FileUpload框架来上传文件,因此,要在web应用中增加两个Jar文件:commons-fileupload-1.2.jarcommons-io-1.3.1.jar。它在原上传框架上做了进一步封装,简化了文件上传的代码实现,取消了不同上传框架上的编程差异。
如果要改成其它的文件上传框架,可以修改struts.multipart.parser常量的值为cos/pell,默认值是jakata。并在classpath中增加相应上传组件的类库。

action文件:

package com.dhcc.itsm.jbpm.actions;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.log4j.Logger;
import com.dhcc.itsm.jbpm.service.ServiceTemplate;
import com.opensymphony.xwork2.ActionSupport;

public class DeployProcessDefinition extends ActionSupport{
 
 private static final long serialVersionUID = 1L;
 private Logger logger = Logger.getLogger(DeployProcessDefinition.class);
 
 private ServiceTemplate serviceTemplate;
 
 private String deployUrlName;
 
    // 上传文件域对象
    private File xmlFile;
   
 public File getXmlFile() {
  return xmlFile;
 }

 public void setXmlFile(File xmlFile) {
  this.xmlFile = xmlFile;
 }

 public String getDeployUrlName() {
  return deployUrlName;
 }

 public void setDeployUrlName(String deployUrlName) {
  this.deployUrlName = deployUrlName;
 }

 public String execute() throws Exception {
  logger.info("DeployProcessDefinition execute------------>");
        InputStream is = new FileInputStream(xmlFile);

//主要是实现把InputStream 对象转化成processDefinition 对象。。然后发布。。
        processDefinitionID = serviceTemplate.deployfromInputStream(is);

/*

InputSource inputSource = new InputSource(is);
  JpdlXmlReader jpdlXmlReader = new JpdlXmlReader(inputSource);
  _processDefinition = jpdlXmlReader.readProcessDefinition();

*/
        return SUCCESS;
    }

    private boolean isInvalid(String value) {
        return (value == null || value.length() == 0);
    }

 public void setServiceTemplate(ServiceTemplate serviceTemplate) {
  this.serviceTemplate = serviceTemplate;
 }
   
}
上诉代码不是全部。。只是提供思想。。

jsp页面

<s:form action="DeployProcessDefinition" name="itsm" method="POST" enctype="multipart/form-data">>
  <table border="0" >
   <tr>
    <td>
     <s:text name="选择您想发布的XML文件" />
    </td>
    <td>
     <s:file name="xmlFile" />
    </td>
   </tr>
   <tr height="20">
   <td colspan="2"></td>
   </tr>
   <tr>
    <td width="20%">
     <s:label label="XML文件名:" tooltip="Enter your Name here"/>
    </td>
    <td width="80%">
     <s:textfield name="deployUrlName" size="80" value=""/>
    </td>
   </tr>
   <tr height="20">
    <td colspan="2"><s:submit value="Submit the form" align="left" /></td>
   </tr>
  </table>
 </s:form>

第2种方法:找到PROJECT中的XML文件。通过JBPM的InputStream is = ClassLoaderUtil.getStream(xmlStr);来生成InputStream 对象。。然后后面的操作和第一种方法相同。

 

 

原创粉丝点击