activiti - 将任务分配给组或用户
activiti - Assigning a task to a group or a user
我在弄清楚如何根据他们 select 在 group/people选择器。
所以在我的 UI 中,用户可以 select 一个 人 或 group 使用相关的 person/group 选择器控件。
使用 activiti 分配属性,我将 Assignee 设置为 ${selectedPerson}
,将 Candidate Groups 设置为 ${selectedGroup}
.这些变量与上述选择器控件的值相关:
总体目标是用户应该能够将任务分配给个人或组,但是上面的设计存在以下问题:
- 当用户select组时,任务被成功分配到组,推测Assignee值可以为空。
- 但是,当用户 select 是一个人而不是一个组时,Activiti 会抛出以下异常,因为它需要一个组;
org.activiti.engine.ActivitiIllegalArgumentException: Expression did
not resolve to a string or collection of strings
正确的做法是什么?
完整的堆栈跟踪
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.activiti.engine.ActivitiIllegalArgumentException: Expression did not resolve to a string or collection of strings
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:97)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:149)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
com.activiti.security.CustomStatelessCSRFFilter.doFilterInternal(CustomStatelessCSRFFilter.java:68)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
这是因为 Activiti 接受候选组的 ID 作为字符串或字符串的逗号分隔值。但是表单元素(如您所选择的)将所选组的组 ID 存储为 Long,因此 IllegalArgumentException
。尝试在用户选择后将变量存储为字符串,然后将此字符串作为候选组传递。
您使用的方法仅在 ${selectedPerson}
和 ${selectedGroup}
都具有非空值时才会满足。
或者,您可以在要分配的任务上创建任务侦听器并执行逻辑。
类似于:
public class CustomTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
// get required variables
String selectedPerson = (String) delegateTask.getVariable("selectedPerson");
String selectedGroup = (String) delegateTask.getVariable("selectedGroup");
// check for the condition
if (null != selectedPerson && !selectedPerson.isEmpty()) {
// set values
delegateTask.setAssignee(selectedPerson);
} else {
delegateTask.addCandidateGroup(selectedGroup);
}
}
}
如果您想将任务分配给用户或组
,则不能同时将两个受让人作为受让人和候选组
然后使用 Candidate Users 作为接受用户数组的受让人,如果您的第一个条件需要 true 则将变量设置为数组然后添加该用户 to array else 迭代组成员并将所有组成员添加到array并通过此数组变量作为受让人候选用户。
我在弄清楚如何根据他们 select 在 group/people选择器。
所以在我的 UI 中,用户可以 select 一个 人 或 group 使用相关的 person/group 选择器控件。
使用 activiti 分配属性,我将 Assignee 设置为 ${selectedPerson}
,将 Candidate Groups 设置为 ${selectedGroup}
.这些变量与上述选择器控件的值相关:
总体目标是用户应该能够将任务分配给个人或组,但是上面的设计存在以下问题:
- 当用户select组时,任务被成功分配到组,推测Assignee值可以为空。
- 但是,当用户 select 是一个人而不是一个组时,Activiti 会抛出以下异常,因为它需要一个组;
org.activiti.engine.ActivitiIllegalArgumentException: Expression did not resolve to a string or collection of strings
正确的做法是什么?
完整的堆栈跟踪
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.activiti.engine.ActivitiIllegalArgumentException: Expression did not resolve to a string or collection of strings
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:97)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:149)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
com.activiti.security.CustomStatelessCSRFFilter.doFilterInternal(CustomStatelessCSRFFilter.java:68)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
这是因为 Activiti 接受候选组的 ID 作为字符串或字符串的逗号分隔值。但是表单元素(如您所选择的)将所选组的组 ID 存储为 Long,因此 IllegalArgumentException
。尝试在用户选择后将变量存储为字符串,然后将此字符串作为候选组传递。
您使用的方法仅在 ${selectedPerson}
和 ${selectedGroup}
都具有非空值时才会满足。
或者,您可以在要分配的任务上创建任务侦听器并执行逻辑。
类似于:
public class CustomTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
// get required variables
String selectedPerson = (String) delegateTask.getVariable("selectedPerson");
String selectedGroup = (String) delegateTask.getVariable("selectedGroup");
// check for the condition
if (null != selectedPerson && !selectedPerson.isEmpty()) {
// set values
delegateTask.setAssignee(selectedPerson);
} else {
delegateTask.addCandidateGroup(selectedGroup);
}
}
}
如果您想将任务分配给用户或组
,则不能同时将两个受让人作为受让人和候选组然后使用 Candidate Users 作为接受用户数组的受让人,如果您的第一个条件需要 true 则将变量设置为数组然后添加该用户 to array else 迭代组成员并将所有组成员添加到array并通过此数组变量作为受让人候选用户。