第一,要将jbpm.mail.template.xml文件放到工程目录classpath下,否则会出现can not parseXML 等错误。
第二,修改jbpm.cfg.xml,添加自己的邮箱信息,如163邮箱:
<string name="jbpm.mail.smtp.host" value="smtp.163.com" /> <string name="jbpm.mail.smtp.port" value="25" /> <bean name="jbpm.mail.address.resolver" class="test.MailResolver" singleton="true" /> <string name="jbpm.mail.from.address" value="XXXX@163.com" /> <!-- 用户名 --> <string name="jbpm.mail.smtp.user" value="XXXX@163.com" /> <!-- 密码 --> <string name="jbpm.mail.smtp.password" value="XXXX" /> <!--!!!!! 邮件安全验证,这个很重要!!!!!!!! --> <string name="jbpm.mail.smtp.auth" value="true" />
第三,编写address resolver类。
package test;
import org.jbpm.mail.AddressResolver;
public class MailResolver implements AddressResolver {
public Object resolveAddress(String actorId) {
if(actorId.equals("XXXX")){
return "XXXX@yahoo.com.cn";
}else{
return "XXXX@163.com";
}
}
}
第四,设计流程,在任务属性中设置notify以及reminder
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="tasknotifytest"> <start-state name="start-state1"> <transition to="task-node1"></transition> </start-state> <task-node name="task-node1"> <task name="test notify task" notify="true"> <assignment actor-id="XXX"></assignment> </task> <transition to="end-state1"></transition> </task-node> <end-state name="end-state1"></end-state> </process-definition>
第五,编写测试类
package test;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.exe.ProcessInstance;
public class TestTaskNotify {
/**
* @param args
*/
public static void main(String[] args) {
JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
try{
ProcessInstance pi = jbpmContext.newProcessInstance("tasknotifytest");
pi.signal();
}finally{
jbpmContext.close();
}
}
}
package test;
import org.jbpm.JbpmConfiguration;
public class JobService {
public static void main(String[] args) {
JbpmConfiguration.getInstance().getJobExecutor().start();
}
}
第六,jbpm3.2.3中的mail类没有设置安全验证,因此需要改写该类,源代码如下,将该类编译后覆盖jbpm-jpdl.jar中的mail.class文件。
package org.jbpm.mail;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmException;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.jpdl.el.ELException;
import org.jbpm.jpdl.el.VariableResolver;
import org.jbpm.jpdl.el.impl.JbpmExpressionEvaluator;
import org.jbpm.security.authentication.DefaultAuthenticationService;
import org.jbpm.util.ClassLoaderUtil;
import org.jbpm.util.XmlUtil;
import org.w3c.dom.Element;
public class Mail implements ActionHandler {
private static final long serialVersionUID = 1L;
String template = null;
String actors = null;
String to = null;
String bcc = null;
String bccActors = null;
String subject = null;
String text = null;
ExecutionContext executionContext = null;
static Map templates = null;
static Map templateVariables = null;
private static Log log = LogFactory.getLog(Mail.class);
public Mail() {
}
public Mail(String template, String actors, String to, String subject,
String text) {
this.template = template;
this.actors = actors;
this.to = to;
this.subject = subject;
this.text = text;
}
public Mail(String template, String actors, String to, String bccActors,
String bcc, String subject, String text) {
this.template = template;
this.actors = actors;
this.to = to;
this.bccActors = bccActors;
this.bcc = bcc;
this.subject = subject;
this.text = text;
}
public void execute(ExecutionContext executionContext) {
this.executionContext = executionContext;
send();
}
public List getRecipients() {
List recipients = new ArrayList();
if (this.actors != null) {
String evaluatedActors = evaluate(this.actors);
List tokenizedActors = tokenize(evaluatedActors);
if (tokenizedActors != null) {
recipients.addAll(resolveAddresses(tokenizedActors));
}
}
if (this.to != null) {
String resolvedTo = evaluate(this.to);
recipients.addAll(tokenize(resolvedTo));
}
return recipients;
}
public List getBccRecipients() {
List recipients = new ArrayList();
if (this.bccActors != null) {
String evaluatedActors = evaluate(this.bccActors);
List tokenizedActors = tokenize(evaluatedActors);
if (tokenizedActors != null) {
recipients.addAll(resolveAddresses(tokenizedActors));
}
}
if (this.bcc != null) {
String resolvedTo = evaluate(this.to);
recipients.addAll(tokenize(resolvedTo));
}
if (JbpmConfiguration.Configs.hasObject("jbpm.mail.bcc.address")) {
recipients.addAll(tokenize(JbpmConfiguration.Configs
.getString("jbpm.mail.bcc.address")));
}
return recipients;
}
public String getSubject() {
if (this.subject == null)
return null;
return evaluate(this.subject);
}
public String getText() {
if (this.text == null)
return null;
return evaluate(this.text);
}
public String getFromAddress() {
if (JbpmConfiguration.Configs.hasObject("jbpm.mail.from.address")) {
return JbpmConfiguration.Configs
.getString("jbpm.mail.from.address");
}
return "jbpm@noreply";
}
public void send() {
if (this.template != null) {
Properties properties = getMailTemplateProperties(this.template);
if (this.actors == null) {
this.actors = properties.getProperty("actors");
}
if (this.to == null) {
this.to = properties.getProperty("to");
}
if (this.subject == null) {
this.subject = properties.getProperty("subject");
}
if (this.text == null) {
this.text = properties.getProperty("text");
}
if (this.bcc == null) {
this.bcc = properties.getProperty("bcc");
}
if (this.bccActors == null) {
this.bccActors = properties.getProperty("bccActors");
}
}
send(getMailServerProperties(), getFromAddress(), getRecipients(),
getBccRecipients(), getSubject(), getText());
}
public static void send(Properties mailServerProperties,
String fromAddress, List recipients, String subject, String text) {
send(mailServerProperties, fromAddress, recipients, null, subject, text);
}
public static void send(Properties mailServerProperties,
String fromAddress, List recipients, List bccRecipients,
String subject, String text) {
if ((recipients == null) || (recipients.isEmpty())) {
log.debug("skipping mail because there are no recipients");
return;
}
log.debug("sending email to '" + recipients + "' about '" + subject
+ "'");
Session session = null;
String auth = JbpmConfiguration.Configs.getString("jbpm.mail.smtp.auth");
mailServerProperties.put("mail.smtp.auth","true");
if(auth!=null && auth.equals("true")){
session = Session.getInstance(mailServerProperties, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(JbpmConfiguration.Configs.getString("jbpm.mail.smtp.user"), JbpmConfiguration.Configs.getString("jbpm.mail.smtp.password"));
}
});
}else{
session = Session.getDefaultInstance(mailServerProperties, null);
}
MimeMessage message = new MimeMessage(session);
try {
if (fromAddress != null) {
message.setFrom(new InternetAddress(fromAddress));
}
Iterator iter = recipients.iterator();
while (iter.hasNext()) {
InternetAddress recipient = new InternetAddress((String) iter
.next());
message.addRecipient(Message.RecipientType.TO, recipient);
}
if (bccRecipients != null) {
iter = bccRecipients.iterator();
while (iter.hasNext()) {
InternetAddress recipient = new InternetAddress(
(String) iter.next());
message.addRecipient(Message.RecipientType.BCC, recipient);
}
}
if (subject != null) {
message.setSubject(subject);
}
if (text != null) {
message.setText(text);
}
message.setSentDate(new Date());
Transport.send(message);
} catch (Exception e) {
throw new JbpmException("couldn't send email", e);
}
}
protected List tokenize(String text) {
if (text == null) {
return null;
}
List list = new ArrayList();
StringTokenizer tokenizer = new StringTokenizer(text, ";:");
while (tokenizer.hasMoreTokens()) {
list.add(tokenizer.nextToken());
}
return list;
}
protected Collection resolveAddresses(List actorIds) {
List emailAddresses = new ArrayList();
Iterator iter = actorIds.iterator();
while (iter.hasNext()) {
String actorId = (String) iter.next();
AddressResolver addressResolver = (AddressResolver) JbpmConfiguration.Configs
.getObject("jbpm.mail.address.resolver");
Object resolvedAddresses = addressResolver.resolveAddress(actorId);
if (resolvedAddresses != null) {
if ((resolvedAddresses instanceof String))
emailAddresses.add((String) resolvedAddresses);
else if ((resolvedAddresses instanceof Collection))
emailAddresses.addAll((Collection) resolvedAddresses);
else if ((resolvedAddresses instanceof String[]))
emailAddresses.addAll(Arrays
.asList((String[]) (String[]) resolvedAddresses));
else {
throw new JbpmException(
"Address resolver '"
+ addressResolver
+ "' returned '"
+ resolvedAddresses.getClass().getName()
+ "' instead of a String, Collection or String-array: "
+ resolvedAddresses);
}
}
}
return emailAddresses;
}
Properties getMailServerProperties() {
Properties mailServerProperties = new Properties();
if (JbpmConfiguration.Configs.hasObject("resource.mail.properties")) {
String mailServerPropertiesResource = JbpmConfiguration.Configs
.getString("resource.mail.properties");
try {
InputStream mailServerStream = ClassLoaderUtil
.getStream(mailServerPropertiesResource);
mailServerProperties.load(mailServerStream);
} catch (Exception e) {
throw new JbpmException(
"couldn't get configuration properties for jbpm mail server from resource '"
+ mailServerPropertiesResource + "'", e);
}
} else if (JbpmConfiguration.Configs.hasObject("jbpm.mail.smtp.host")) {
String smtpServer = JbpmConfiguration.Configs
.getString("jbpm.mail.smtp.host");
mailServerProperties.put("mail.smtp.host", smtpServer);
} else {
log.error("couldn't get mail properties");
}
return mailServerProperties;
}
synchronized Properties getMailTemplateProperties(String templateName) {
if (templates == null) {
templates = new HashMap();
String mailTemplatesResource = JbpmConfiguration.Configs
.getString("resource.mail.templates");
Element mailTemplatesElement = XmlUtil.parseXmlResource(
mailTemplatesResource).getDocumentElement();
List mailTemplateElements = XmlUtil.elements(mailTemplatesElement,
"mail-template");
Iterator iter = mailTemplateElements.iterator();
while (iter.hasNext()) {
Element mailTemplateElement = (Element) iter.next();
Properties templateProperties = new Properties();
addTemplateProperty(mailTemplateElement, "actors",
templateProperties);
addTemplateProperty(mailTemplateElement, "to",
templateProperties);
addTemplateProperty(mailTemplateElement, "subject",
templateProperties);
addTemplateProperty(mailTemplateElement, "text",
templateProperties);
addTemplateProperty(mailTemplateElement, "bcc",
templateProperties);
addTemplateProperty(mailTemplateElement, "bccActors",
templateProperties);
templates.put(mailTemplateElement.getAttribute("name"),
templateProperties);
}
templateVariables = new HashMap();
List variableElements = XmlUtil.elements(mailTemplatesElement,
"variable");
iter = variableElements.iterator();
while (iter.hasNext()) {
Element variableElement = (Element) iter.next();
templateVariables.put(variableElement.getAttribute("name"),
variableElement.getAttribute("value"));
}
}
return (Properties) templates.get(templateName);
}
void addTemplateProperty(Element mailTemplateElement, String property,
Properties templateProperties) {
Element element = XmlUtil.element(mailTemplateElement, property);
if (element != null)
templateProperties.put(property, XmlUtil.getContentText(element));
}
String evaluate(String expression) {
if (expression == null) {
return null;
}
VariableResolver variableResolver = JbpmExpressionEvaluator
.getUsedVariableResolver();
if (variableResolver != null) {
variableResolver = new MailVariableResolver(templateVariables,
variableResolver);
}
return (String) JbpmExpressionEvaluator.evaluate(expression,
this.executionContext, variableResolver, null);
}
class MailVariableResolver implements VariableResolver, Serializable {
private static final long serialVersionUID = 1L;
Map templateVariables = null;
VariableResolver variableResolver = null;
public MailVariableResolver(Map templateVariables,
VariableResolver variableResolver) {
this.templateVariables = templateVariables;
this.variableResolver = variableResolver;
}
public Object resolveVariable(String pName) throws ELException {
if ((this.templateVariables != null)
&& (this.templateVariables.containsKey(pName))) {
return this.templateVariables.get(pName);
}
return this.variableResolver.resolveVariable(pName);
}
}
}
其中蓝色部分是进行了修改的部分,要特别注意的是红色部分,设置进行安全验证,如果没有该句,那么会出现553 authentication is required错误。
好了,将流程部署到数据库中,运行JobService,在运行TestTaskNotify ,可以看到邮件已将发出去了。