14.4. 以表单或流程形式进行文档附件


Red Hat Process Automation Manager 支持使用 Document 表单字段以表单形式进行文档附加。使用 Document 表单字段,您可以上传表单或流程中所需的文档。

要以表单和流程启用文档附件,请完成以下步骤:

  1. 设置文档总结策略。
  2. 在业务流程中创建文档变量。
  3. 将任务输入和输出映射到 document 变量。

14.4.1. 设置文档摘要策略

项目的文档总结策略决定了文档与表单和流程相关的存储位置。Red Hat Process Automation Manager 中的默认文档摘要策略是 org.jbpm.document.marshalling.DocumentMarshallingStrategy。此策略使用 DocumentStorageServiceImpl 类,将文档存储在本地存储在 PROJECT_HOME/.docs 文件夹中。您可以在 Business Central 或 kie-deployment-descriptor.xml 文件中为项目设置本文档 marshalling 策略或自定义文档 marshalling 策略。

流程

  1. 在 Business Central 中,转至 Menu Design Projects
  2. 选择项目。project Assets 窗口将打开。
  3. Settings 标签页。

    图 14.3. 设置标签页

    选择设置标签页
  4. Deployments MarshallingStrategy Add Marshalling Strategy
  5. Name 字段中输入文档摘要策略的标识符,并在 Resolver 下拉菜单中选择对应的解析器类型:

    • 对于单文:输入 org.jbpm.document.marshalling.DocumentMarshallingStrategy 作为文档总结策略,并将解析器类型设置为 Reflection
    • 对于多个文档:输入 新的 org.jbpm.document.marshalling.DocumentCollectionImplMarshallingStrategy(new org.jbpm.document.marshalling.DocumentMarshallingStrategy()) 作为文档 marshalling 策略,并将解析器类型设置为 MVEL
    • 对于自定义文档支持:输入自定义文档总结策略的标识符并选择相关解析器类型。
  6. 单击 Test 以验证您的部署描述符文件。
  7. 单击 Deploy to build 并部署更新的项目。

    或者,如果您不使用 Business Central,您可以导航到 PROJECT_HOME/src/main/resources/META_INF/kie-deployment-descriptor.xml (如果适用)并使用所需的 < marshalling-strategies > 元素编辑部署描述符文件。

  8. 点击 Save

具有多个文档的部署描述符文件示例

<deployment-descriptor
    xsi:schemaLocation="http://www.jboss.org/jbpm deployment-descriptor.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <persistence-unit>org.jbpm.domain</persistence-unit>
  <audit-persistence-unit>org.jbpm.domain</audit-persistence-unit>
  <audit-mode>JPA</audit-mode>
  <persistence-mode>JPA</persistence-mode>
  <runtime-strategy>SINGLETON</runtime-strategy>
  <marshalling-strategies>
    <marshalling-strategy>
      <resolver>mvel</resolver>
      <identifier>new org.jbpm.document.marshalling.DocumentCollectionImplMarshallingStrategy(new org.jbpm.document.marshalling.DocumentMarshallingStrategy());</identifier>
    </marshalling-strategy>
  </marshalling-strategies>
Copy to Clipboard Toggle word wrap

项目的文档总结策略决定了文档与表单和流程相关的存储位置。Red Hat Process Automation Manager 中的默认文档摘要策略是 org.jbpm.document.marshalling.DocumentMarshallingStrategy。此策略使用 DocumentStorageServiceImpl 类,将文档存储在本地存储在 PROJECT_HOME/.docs 文件夹中。如果要在自定义位置存储表单和流程文档,如集中内容管理系统(CMS),请在项目中添加自定义文档摘要策略。您可以在 Business Central 或 kie-deployment-descriptor.xml 文件中设置本文档。

流程

  1. 创建自定义 marshalling 策略 .java 文件,其中包含 org.kie.api.marshalling.ObjectMarshallingStrategy 接口的实施。这个接口可让您实施自定义文档总结策略所需的变量持久性。

    这个接口中的以下方法可帮助您创建策略:

    • 布尔值接受(Object 对象): 确定策略是否可以被汇总指定对象
    • byte[] marshal(Context context, ObjectOutput os, Object object): Marshals the specified 对象并将 marshalled 对象返回为 byte[]
    • Object unmarshal(Context context, ObjectInputStream is, byte[] 对象, ClassLoader classloader): 阅读作为 byte[] 接收的对象并返回 unmarshalled 对象
    • void write(ObjectOutputStream os, Object object): Same 作为 marshal 方法,提供向后兼容
    • 对象 read(ObjectInputStream os): Same 作为 unmarshal 方法,为向后兼容提供

    以下代码示例是 ObjectMarshallingStrategy 实施示例,用于从 Content Management Interoperability Services(CMIS)系统存储和检索数据:

    从 CMIS 系统存储和检索数据的实现示例

    package org.jbpm.integration.cmis.impl;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.HashMap;
    
    import org.apache.chemistry.opencmis.client.api.Folder;
    import org.apache.chemistry.opencmis.client.api.Session;
    import org.apache.chemistry.opencmis.commons.data.ContentStream;
    import org.apache.commons.io.IOUtils;
    import org.drools.core.common.DroolsObjectInputStream;
    import org.jbpm.document.Document;
    import org.jbpm.integration.cmis.UpdateMode;
    
    import org.kie.api.marshalling.ObjectMarshallingStrategy;
    
    public class OpenCMISPlaceholderResolverStrategy extends OpenCMISSupport implements ObjectMarshallingStrategy {
    
    	private String user;
    	private String password;
    	private String url;
    	private String repository;
    	private String contentUrl;
    	private UpdateMode mode = UpdateMode.OVERRIDE;
    
    	public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository) {
    		this.user = user;
    		this.password = password;
    		this.url = url;
    		this.repository = repository;
    	}
    
    	public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository, UpdateMode mode) {
    		this.user = user;
    		this.password = password;
    		this.url = url;
    		this.repository = repository;
    		this.mode = mode;
    	}
    
    	   public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository, String contentUrl) {
    	        this.user = user;
    	        this.password = password;
    	        this.url = url;
    	        this.repository = repository;
    	        this.contentUrl = contentUrl;
    	    }
    
    	    public OpenCMISPlaceholderResolverStrategy(String user, String password, String url, String repository, String contentUrl, UpdateMode mode) {
    	        this.user = user;
    	        this.password = password;
    	        this.url = url;
    	        this.repository = repository;
    	        this.contentUrl = contentUrl;
    	        this.mode = mode;
    	    }
    
    	public boolean accept(Object object) {
    		if (object instanceof Document) {
    			return true;
    		}
    		return false;
    	}
    
    	public byte[] marshal(Context context, ObjectOutputStream os, Object object) throws IOException {
    		Document document = (Document) object;
    		Session session = getRepositorySession(user, password, url, repository);
    		try {
    			if (document.getContent() != null) {
    				String type = getType(document);
    				if (document.getIdentifier() == null || document.getIdentifier().isEmpty()) {
    					String location = getLocation(document);
    
    					Folder parent = findFolderForPath(session, location);
    					if (parent == null) {
    						parent = createFolder(session, null, location);
    					}
    					org.apache.chemistry.opencmis.client.api.Document doc = createDocument(session, parent, document.getName(), type, document.getContent());
    					document.setIdentifier(doc.getId());
    					document.addAttribute("updated", "true");
    				} else {
    					if (document.getContent() != null && "true".equals(document.getAttribute("updated"))) {
    						org.apache.chemistry.opencmis.client.api.Document doc = updateDocument(session, document.getIdentifier(), type, document.getContent(), mode);
    
    						document.setIdentifier(doc.getId());
    						document.addAttribute("updated", "false");
    					}
    				}
    			}
    			ByteArrayOutputStream buff = new ByteArrayOutputStream();
    	        ObjectOutputStream oos = new ObjectOutputStream( buff );
    	        oos.writeUTF(document.getIdentifier());
    	        oos.writeUTF(object.getClass().getCanonicalName());
    	        oos.close();
    	        return buff.toByteArray();
    		} finally {
    			session.clear();
    		}
    	}
    
    	public Object unmarshal(Context context, ObjectInputStream ois, byte[] object, ClassLoader classloader) throws IOException, ClassNotFoundException {
    		DroolsObjectInputStream is = new DroolsObjectInputStream( new ByteArrayInputStream( object ), classloader );
    		String objectId = is.readUTF();
    		String canonicalName = is.readUTF();
    		Session session = getRepositorySession(user, password, url, repository);
    		try {
    			org.apache.chemistry.opencmis.client.api.Document doc = (org.apache.chemistry.opencmis.client.api.Document) findObjectForId(session, objectId);
    			Document document = (Document) Class.forName(canonicalName).newInstance();
    			document.setAttributes(new HashMap<String, String>());
    
    			document.setIdentifier(objectId);
    			document.setName(doc.getName());
    			document.setLastModified(doc.getLastModificationDate().getTime());
    			document.setSize(doc.getContentStreamLength());
    			document.addAttribute("location", getFolderName(doc.getParents()) + getPathAsString(doc.getPaths()));
    			if (doc.getContentStream() != null && contentUrl == null) {
    				ContentStream stream = doc.getContentStream();
    				document.setContent(IOUtils.toByteArray(stream.getStream()));
    				document.addAttribute("updated", "false");
    				document.addAttribute("type", stream.getMimeType());
    			} else {
    			    document.setLink(contentUrl + document.getIdentifier());
    			}
    			return document;
    		} catch(Exception e) {
    			throw new RuntimeException("Cannot read document from CMIS", e);
    		} finally {
    			is.close();
    			session.clear();
    		}
    	}
    
    	public Context createContext() {
    		return null;
    	}
    
    	// For backward compatibility with previous serialization mechanism
    	public void write(ObjectOutputStream os, Object object) throws IOException {
    		Document document = (Document) object;
    		Session session = getRepositorySession(user, password, url, repository);
    		try {
    			if (document.getContent() != null) {
    				String type = document.getAttribute("type");
    				if (document.getIdentifier() == null) {
    					String location = document.getAttribute("location");
    
    					Folder parent = findFolderForPath(session, location);
    					if (parent == null) {
    						parent = createFolder(session, null, location);
    					}
    					org.apache.chemistry.opencmis.client.api.Document doc = createDocument(session, parent, document.getName(), type, document.getContent());
    					document.setIdentifier(doc.getId());
    					document.addAttribute("updated", "false");
    				} else {
    					if (document.getContent() != null && "true".equals(document.getAttribute("updated"))) {
    						org.apache.chemistry.opencmis.client.api.Document doc = updateDocument(session, document.getIdentifier(), type, document.getContent(), mode);
    
    						document.setIdentifier(doc.getId());
    						document.addAttribute("updated", "false");
    					}
    				}
    			}
    			ByteArrayOutputStream buff = new ByteArrayOutputStream();
    	        ObjectOutputStream oos = new ObjectOutputStream( buff );
    	        oos.writeUTF(document.getIdentifier());
    	        oos.writeUTF(object.getClass().getCanonicalName());
    	        oos.close();
    		} finally {
    			session.clear();
    		}
    	}
    
    	public Object read(ObjectInputStream os) throws IOException, ClassNotFoundException {
    		String objectId = os.readUTF();
    		String canonicalName = os.readUTF();
    		Session session = getRepositorySession(user, password, url, repository);
    		try {
    			org.apache.chemistry.opencmis.client.api.Document doc = (org.apache.chemistry.opencmis.client.api.Document) findObjectForId(session, objectId);
    			Document document = (Document) Class.forName(canonicalName).newInstance();
    
    			document.setIdentifier(objectId);
    			document.setName(doc.getName());
    			document.addAttribute("location", getFolderName(doc.getParents()) + getPathAsString(doc.getPaths()));
    			if (doc.getContentStream() != null) {
    				ContentStream stream = doc.getContentStream();
    				document.setContent(IOUtils.toByteArray(stream.getStream()));
    				document.addAttribute("updated", "false");
    				document.addAttribute("type", stream.getMimeType());
    			}
    			return document;
    		} catch(Exception e) {
    			throw new RuntimeException("Cannot read document from CMIS", e);
    		} finally {
    			session.clear();
    		}
    	}
    
    }
    Copy to Clipboard Toggle word wrap

  2. 在 Business Central 中,转至 Menu Design Projects
  3. 单击项目名称,再单击 Settings

    图 14.4. 设置标签页

    选择设置标签页
  4. Deployments MarshallingStrategy Add Marshalling Strategy
  5. Name 字段中输入自定义文档 marshalling 策略的标识符,如 org.jbpm.integration.cmis.impl.OpenCMISPlaceholderResolverStrategy
  6. Resolver 下拉菜单中选择相关选项,如本例中的 Reflection
  7. 单击 Test 以验证您的部署描述符文件。
  8. 单击 Deploy to build 并部署更新的项目。

    或者,如果您不使用 Business Central,您可以导航到 PROJECT_HOME/src/main/resources/META_INF/kie-deployment-descriptor.xml (如果适用)并使用所需的 < marshalling-strategies > 元素编辑部署描述符文件。

    具有自定义文档总结策略的部署描述符文件示例

    <deployment-descriptor
        xsi:schemaLocation="http://www.jboss.org/jbpm deployment-descriptor.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <persistence-unit>org.jbpm.domain</persistence-unit>
      <audit-persistence-unit>org.jbpm.domain</audit-persistence-unit>
      <audit-mode>JPA</audit-mode>
      <persistence-mode>JPA</persistence-mode>
      <runtime-strategy>SINGLETON</runtime-strategy>
      <marshalling-strategies>
        <marshalling-strategy>
          <resolver>reflection</resolver>
          <identifier>
            org.jbpm.integration.cmis.impl.OpenCMISPlaceholderResolverStrategy
          </identifier>
        </marshalling-strategy>
      </marshalling-strategies>
    Copy to Clipboard Toggle word wrap

  9. 要启用存储在自定义位置的文档要附加到表单和进程,在相关流程中创建文档变量,并将任务输入和输出映射到 Business Central 中的变量。

14.4.2. 在业务流程中创建文档变量

设置文档总结策略后,请在相关流程中创建一个文档变量,以便将文档上传到人工任务,并为 Business Central 中的 流程实例 视图显示文档或文档。

先决条件

流程

  1. 在 Business Central 中,转至 Menu Design Projects
  2. 点击项目名称以打开资产视图,并点击业务流程名称。
  3. 点 canvas 并点窗口右侧的 the Properties icon 来打开 Properties 面板。
  4. 展开 Process Data 并点 6176 并输入以下值:

    • 名称文档
    • custom Type:org.jbpm.document.Document for a single document or org.jbpm.document.DocumentCollection for multiple Documentation

14.4.3. 将任务输入和输出到文档变量

如果要在任务表单中查看或修改附件,请在任务输入和输出中创建分配。

先决条件

  • 您有一个包含至少包含一个用户任务的业务流程资产的项目。

流程

  1. 在 Business Central 中,转至 Menu Design Projects
  2. 点击项目名称以打开资产视图,并点击业务流程名称。
  3. 点击用户任务并点击窗口右侧的 the Properties icon 打开 Properties 面板。
  4. 展开 Implementation/Execution,并在 分配 旁边点 btn assign 打开 Data I/O 窗口。
  5. Data Inputs and Assignments 下,点 Add 并输入以下值:

    • 名称taskdoc_in
    • Data Type:org.jbpm.document.Document for a single document or org.jbpm.document.DocumentCollection for multiple Documentation
    • 文档
  6. Data Outputs and Assignments 下,点 Add 并输入以下值:

    • Name:taskdoc_out
    • Data Type:org.jbpm.document.Document for a single document or org.jbpm.document.DocumentCollection for multiple Documentation
    • 目标文档

    SourceTarget 字段包含您之前创建的进程变量的名称。

  7. 点击 Save
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat
返回顶部