当前位置: 首页 > 工具软件 > Mail2Bug > 使用案例 >

jbpm4.4中mail组件发邮件bug

穆博简
2023-12-01

jbpm4.4中使用mail组件发邮件时要求smtp 验证用户,jbpm那个类没有实现权限验证的连接。 
注释代码经过修改,实现了smtp验证服务器发邮件。测试成功!

public class MailSessionImpl implements MailSession {

  private List<MailServer> mailServers;

  public void send(Collection<Message> emails) {
	  //自定义代码,加载配置文件并读取信息
	  InputStream is = this.getClass().getResourceAsStream("/jbpm.mail.properties");
	  Properties props = new Properties();
	  String user = null;
	  String password = null;
	  String host = null;
	  try {
		props.load(is);
		host = props.getProperty("mail.smtp.host");
		user = props.getProperty("mail.from");
		password = props.getProperty("mail.smtp.password");
	} catch (IOException e1) {
		e1.printStackTrace();
	}
	  
	  
    // Emails need to have the sessions populated.
    for (Message email : emails) {
      try {
        Address[] to = email.getRecipients(RecipientType.TO);
        Address[] cc = email.getRecipients(RecipientType.CC);
        Address[] bcc = email.getRecipients(RecipientType.BCC);

        for (MailServer mailServer : mailServers) {
          // Need to apply filter.
          AddressFilter addressFilter = mailServer.getAddressFilter();
          if (addressFilter != null) {
            // Set the email with the new filtered addresses.
            email.setRecipients(RecipientType.TO, addressFilter.filter(to));
            email.setRecipients(RecipientType.CC, addressFilter.filter(cc));
            email.setRecipients(RecipientType.BCC, addressFilter.filter(bcc));
          }

          // if sender is not present, use local address
          Session mailSession = mailServer.getMailSession();
          if (email.getFrom() == null) {
            email.setFrom(InternetAddress.getLocalAddress(mailSession));
          }

          // If there is someone to send it to, then send it.
          Address[] recipients = email.getAllRecipients();
          if (recipients.length > 0) {
            Transport transport = mailSession.getTransport(recipients[0]);
            try {
              //transport.connect();注释掉这行换成下面的
              transport.connect(host, user, password);
              transport.sendMessage(email, recipients);
            }
            finally {
              transport.close();
            }
          }
        }
      }
      catch (MessagingException e) {
        throw new JbpmException("could not send email: " + email, e);
      }
    }
  }

  public List<MailServer> getMailServers() {
    return mailServers;
  }

  protected void setMailServers(List<MailServer> mailServers) {
    this.mailServers = mailServers;
  }

}


 但是这样有个不好的地方,因为JBPM4支付多个mail服务器,即可以配置多个<mail-server>元素,这样相当于是绕过了<mail-server>配置,直接自己去读取了配置文件,当然你也可以在jbpm.mail.properties中进行配置多个mail host等,再经过一定的解析,解析出多个mail服务信息,再进行发送。

还有种做法是:

首先配置jbpm.cfg.xml.在这个文件中,默认导入了jbpm.default.cfg.xml. 这个文件里配置了mail的信息,但是没有配置authenticator信息,为了改他的配置,在我们的jbpm.cfg.xml中不再导入jbpm.default.cfg.xml. 这个文件,新建一个jbpm.customer.cfg.xml.文件,把原来jbpm.default.cfg.xml.中的内容拷过来,在其中加入authenticator的配置,如下:

<mail-server>
        <session-properties resource="jbpm.mail.properties" />
        <authenticator class= "com.xtayfjpk.oa.mail.authenticator.MyMailAuthenticator" > 
          <field name="username" ><string value= "user@qq.com" /></field> 
          <field name="password" ><string value= "password"/></field> 
         </authenticator>
      </mail-server>


这样也是需要覆盖掉JBPM4原有的MailSessionImpl为,作一定的修改,代码如下:

public class MailSessionImpl implements MailSession {

  private List<MailServer> mailServers;

  public void send(Collection<Message> emails) {	  
	  
    // Emails need to have the sessions populated.
    for (Message email : emails) {
      try {
        Address[] to = email.getRecipients(RecipientType.TO);
        Address[] cc = email.getRecipients(RecipientType.CC);
        Address[] bcc = email.getRecipients(RecipientType.BCC);

        for (MailServer mailServer : mailServers) {
          // Need to apply filter.
          AddressFilter addressFilter = mailServer.getAddressFilter();
          if (addressFilter != null) {
            // Set the email with the new filtered addresses.
            email.setRecipients(RecipientType.TO, addressFilter.filter(to));
            email.setRecipients(RecipientType.CC, addressFilter.filter(cc));
            email.setRecipients(RecipientType.BCC, addressFilter.filter(bcc));
          }

          // if sender is not present, use local address
          Session mailSession = mailServer.getMailSession();
          if (email.getFrom() == null) {
            email.setFrom(InternetAddress.getLocalAddress(mailSession));
          }

          // If there is someone to send it to, then send it.
          Address[] recipients = email.getAllRecipients();
          if (recipients.length > 0) {
            Transport transport = mailSession.getTransport(recipients[0]);
            try {
             //这里是修改的地方
              Message msg = new MimeMessage(mailSession);
              try {
				msg.setText((String) email.getContent());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
              msg.setSubject(email.getSubject());
              msg.setFrom(email.getFrom()[0]);
              msg.setReplyTo(email.getReplyTo());
              msg.setSentDate(new Date());
              Transport.send(msg, recipients);
            }
            finally {
              transport.close();
            }
          }
        }
      }
      catch (MessagingException e) {
        throw new JbpmException("could not send email: " + email, e);
      }
    }
  }

  public List<MailServer> getMailServers() {
    return mailServers;
  }

  protected void setMailServers(List<MailServer> mailServers) {
    this.mailServers = mailServers;
  }

}

至于上面为什么要将email对象中的内容复制到一个新msg对象中,主要是要为msg设置mailSession,不然的话就会报错。

这样的话可以读取到多个mail服务器了。

 类似资料: