如何仅使用Java更新alfresco工作流任务中的自定义属性?

如何仅使用Java更新alfresco工作流任务中的自定义属性?,java,alfresco,alfresco-webscripts,Java,Alfresco,Alfresco Webscripts,首先,我要感谢所有花时间帮助我解决这个问题的人,因为我花了一个多星期的时间寻找解决问题的方法。这是: 我的目标是在AlfrescoCommunity5.2中启动一个自定义工作流,并在第一个任务中通过仅使用公共JavaAPI的web脚本设置一些自定义属性。我的班级正在扩展AbstractWebScript。目前,我已成功启动工作流并设置bpm:workflowDescription等属性,但无法在任务中设置自定义属性 代码如下: public class StartWorkflow ext

首先,我要感谢所有花时间帮助我解决这个问题的人,因为我花了一个多星期的时间寻找解决问题的方法。这是:

我的目标是在AlfrescoCommunity5.2中启动一个自定义工作流,并在第一个任务中通过仅使用公共JavaAPI的web脚本设置一些自定义属性。我的班级正在扩展AbstractWebScript。目前,我已成功启动工作流并设置bpm:workflowDescription等属性,但无法在任务中设置自定义属性

代码如下:

    public class StartWorkflow extends AbstractWebScript {
    /**
     * The Alfresco Service Registry that gives access to all public content services in Alfresco.
     */
    private ServiceRegistry serviceRegistry;

    public void setServiceRegistry(ServiceRegistry serviceRegistry) {
        this.serviceRegistry = serviceRegistry;
    }

    @Override
    public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException {       

        // Create JSON object for the response
        JSONObject obj = new JSONObject();

        try {                        
            // Check if parameter defName is present in the request            
            String wfDefFromReq = req.getParameter("defName");
            if (wfDefFromReq == null) {
                obj.put("resultCode", "1 (Error)");
                obj.put("errorMessage", "Parameter defName not found.");
                return;      
            }            
            // Get the WFL Service
            WorkflowService workflowService = serviceRegistry.getWorkflowService();
            // Build WFL Definition name
            String wfDefName = "activiti$" + wfDefFromReq;
            // Get WorkflowDefinition object
            WorkflowDefinition wfDef = workflowService.getDefinitionByName(wfDefName);
            // Check if such WorkflowDefinition exists
            if (wfDef == null) {
                obj.put("resultCode", "1 (Error)");
                obj.put("errorMessage", "No workflow definition found for defName = " + wfDefName);
                return;
            }                       

            // Get parameters from the request
            Content reqContent = req.getContent();
            if (reqContent == null) {
                throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing request body.");
            }
            String content;
            content = reqContent.getContent();

            if (content.isEmpty()) {
                throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Content is empty");
            }

            JSONTokener jsonTokener = new JSONTokener(content);
            JSONObject json = new JSONObject(jsonTokener);           

            // Set the workflow description
            Map<QName, Serializable> params = new HashMap();
            params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "Workflow started from JAVA API");          

            // Start the workflow
            WorkflowPath wfPath = workflowService.startWorkflow(wfDef.getId(), params);

            // Get params from the POST request
            Map<QName, Serializable> reqParams = new HashMap();
            Iterator<String> i = json.keys();
            while (i.hasNext()) {
                String paramName = i.next();
                QName qName = QName.createQName(paramName);
                String value = json.getString(qName.getLocalName());
                reqParams.put(qName, value);  
            }

            // Try to update the task properties

            // Get the next active task which contains the properties to update
            WorkflowTask wfTask = workflowService.getTasksForWorkflowPath(wfPath.getId()).get(0);
            // Update properties
            WorkflowTask updatedTask = workflowService.updateTask(wfTask.getId(), reqParams, null, null);

            obj.put("resultCode", "0 (Success)");
            obj.put("workflowId", wfPath.getId());

        } catch (JSONException e) {
            throw new WebScriptException(Status.STATUS_BAD_REQUEST, 
                    e.getLocalizedMessage());
        } catch (IOException ioe) {
            throw new WebScriptException(Status.STATUS_BAD_REQUEST, 
                    "Error when parsing the request.", 
                    ioe);
        } finally {
            // build a JSON string and send it back
            String jsonString = obj.toString();
            res.getWriter().write(jsonString);
        }

    }  
}
在postParams.json文件中,我有需要更新的属性/值所需的对:

{
"cmprop:propOne" : "Value 1",
"cmprop:propTwo" : "Value 2",
"cmprop:propThree" : "Value 3"
}

工作流已启动,bpm:workflowDescription设置正确,但任务中的属性不可见,无法进行设置

我制作了一个JS脚本,在工作流启动时调用该脚本:

execution.setVariable('bpm_workflowDescription', 'Some String ' + execution.getVariable('cmprop:propOne'));
实际上,使用了cmprop:propOne的值,并且描述被正确更新了-这意味着这些属性在某个地方被更新了(可能在执行级别上?),但我无法理解为什么在打开任务时它们不可见

我成功地启动了工作流并使用JavaScript API更新了属性,包括:

if (wfdef) {

        // Get the params
        wfparams = {};
        if (jsonRequest) {
            for ( var prop in jsonRequest) {
                wfparams[prop] = jsonRequest[prop];
            }
        }

        wfpackage = workflow.createPackage();

        wfpath = wfdef.startWorkflow(wfpackage, wfparams);
问题是我只想使用公共JavaAPI,请帮助。
谢谢

您是否在任务中本地设置变量?在我看来,您似乎是在执行级别定义变量,而不是在状态级别。如果查看ootb adhoc.bpmn20.xml文件(),您会注意到一个在本地设置变量的事件侦听器:

<extensionElements>
    <activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
       <activiti:field name="script">
          <activiti:string>
           if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
           if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
          </activiti:string>
       </activiti:field>
    </activiti:taskListener>
</extensionElements>

if(bpm_workflowDueDate的类型!=“未定义”)task.setVariableLocal(“bpm_dueDate”,bpm_workflowDueDate);
如果(bpm_workflowPriority的类型!=“未定义”)task.priority=bpm_workflowPriority;

通常,我只是尝试导入自定义模型前缀的所有任务。所以对你来说,应该是这样的:

import java.util.Set;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.apache.log4j.Logger;

public class ImportVariables extends AbstractTaskListener {

    private Logger logger = Logger.getLogger(ImportVariables.class);

    @Override
    public void notify(DelegateTask task) {

        logger.debug("Inside ImportVariables.notify()");
        logger.debug("Task ID:" + task.getId());
        logger.debug("Task name:" + task.getName());
        logger.debug("Task proc ID:" + task.getProcessInstanceId());
        logger.debug("Task def key:" + task.getTaskDefinitionKey());

        DelegateExecution execution = task.getExecution();

        Set<String> executionVariables = execution.getVariableNamesLocal();
        for (String variableName : executionVariables) {
            // If the variable starts by "cmprop_"
            if (variableName.startsWith("cmprop_")) {
                // Publish it at the task level
                task.setVariableLocal(variableName, execution.getVariableLocal(variableName));
            }
        }
    }

}
import java.util.Set;
导入org.activiti.engine.delegate.DelegateExecution;
导入org.activiti.engine.delegate.DelegateTask;
导入org.apache.log4j.Logger;
公共类ImportVariables扩展了AbstractTaskListener{
私有记录器=Logger.getLogger(ImportVariables.class);
@凌驾
公共作废通知(委托任务){
debug(“Inside ImportVariables.notify()”;
debug(“任务ID:+Task.getId());
debug(“任务名称:”+Task.getName());
debug(“任务进程ID:+Task.getProcessInstanceId());
debug(“任务定义键:+Task.getTaskDefinitionKey());
DelegateExecution=task.getExecution();
Set executionVariables=execution.getVariableNamesLocal();
for(字符串变量名称:executionVariables){
//如果变量以“cmprop_389;”开头
if(variableName.startsWith(“cmprop_”)){
//在任务级别发布它
task.setVariableLocal(variableName,execution.getVariableLocal(variableName));
}
}
}
}

我试过:
if(typeof cmprop_propOne!=“undefined”)task.setVariableLocal('cmprop_propOne',execution.getVariable('cmprop_propOne')但仍然没有成功。我缺少什么?我尝试使用task.setVariable和task.setVariableLocal,但都没有成功。由于某种原因,在使用javascript时,所有属性在执行和任务级别都是可见的,但在使用Java API时,这些属性仅在执行级别可见:?另外,
workflowService.updateTask(wfTask.getId(),reqParams,null,null)也不会使属性可见。感谢Ben的回答。我已经试过了,但我不得不使用
ImportVariables extensed BaseJavaDelegate实现tasklister
。事实上,在我做了更多的测试之后,我发现了一些非常奇怪的事情:似乎即使没有这个侦听器,属性也在更新,但是出于某种原因Alfresco没有显示它们?!?我做了以下测试:使用webscript启动了一个工作流,然后我检查了任务,没有填充任何内容。然后,当我检查同一任务时,我只是重新启动了应用程序服务器,没有做任何其他事情-属性是可见的…此外,如果我使用webscript启动另一个工作流,那么之前启动的工作流和新工作流的属性将再次消失,直到我重新启动应用程序服务器。重新启动后,两个工作流的属性都在任务中可见。你或任何人知道为什么会发生这种情况吗?
import java.util.Set;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.apache.log4j.Logger;

public class ImportVariables extends AbstractTaskListener {

    private Logger logger = Logger.getLogger(ImportVariables.class);

    @Override
    public void notify(DelegateTask task) {

        logger.debug("Inside ImportVariables.notify()");
        logger.debug("Task ID:" + task.getId());
        logger.debug("Task name:" + task.getName());
        logger.debug("Task proc ID:" + task.getProcessInstanceId());
        logger.debug("Task def key:" + task.getTaskDefinitionKey());

        DelegateExecution execution = task.getExecution();

        Set<String> executionVariables = execution.getVariableNamesLocal();
        for (String variableName : executionVariables) {
            // If the variable starts by "cmprop_"
            if (variableName.startsWith("cmprop_")) {
                // Publish it at the task level
                task.setVariableLocal(variableName, execution.getVariableLocal(variableName));
            }
        }
    }

}