使用JavaMail发送邮件时判断发送结果和设置超时

一笑奈何 提交于 2020-12-10 02:35:21

1、获取邮件发送结果

    网上看大多数例子,都是调用Transport类的sendMessage方法后就收工了。但 sendMessage方法没有返回值的,而且是一个异步的方法(也就是函数调用结束的时候邮件的发送过程并未结束)。我们可以通过 Transport的addTransportListener方法增加邮件发送结果的Listener,Listener 接口有三个方法:
void messageDelivered(TransportEvent arg0);                 // 邮件发送成功
void messageNotDelivered(TransportEvent arg0);            // 邮件发送失败
void messagePartiallyDelivered(TransportEvent arg0);    // 邮件部分发送成功
      注意,由于 sendMessage是异步方法,我们不能简单的:  addTransportListener ->  sendMessage -> 判断发送是否成功,因为这时候邮件发送的过程可能还没有结束。我们可以通过多线程Future模式来将异步的调用转为阻塞的同步调用,Future相关的代码:
private enum DeliveredState {
       INITIAL, MESSAGE_DELIVERED, MESSAGE_NOT_DELIVERED, MESSAGE_PARTIALLY_DELIVERED,
 }
 private static class DeliveredStateFuture {
       private DeliveredState state = DeliveredState.INITIAL;
       synchronized void waitForReady() throws InterruptedException {
           if (state == DeliveredState.INITIAL) {
              wait();
           }
       }
       synchronized DeliveredState getState() {
           return state;
       }
       synchronized void setState(DeliveredState newState) {
           state = newState;
          notifyAll();
       }
}

发送邮件的部分控制代码:

final DeliveredStateFuture future = new DeliveredStateFuture();
transport.addTransportListener(new TransportListener() {
    public void messageDelivered(TransportEvent arg0) {
      future.setState(DeliveredState.MESSAGE_DELIVERED);
    }
    public void messageNotDelivered(TransportEvent arg0) {
      future.setState(DeliveredState.MESSAGE_NOT_DELIVERED);
    }
    public void messagePartiallyDelivered(TransportEvent arg0) {
      future.setState(DeliveredState.MESSAGE_PARTIALLY_DELIVERED);
    }
});
transport.connect();
transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
future.waitForReady();
  2、设置连接超时和读超时
    使用JavaMail用SMTP发送邮件,可以通过 mail.smtp.connectiontimeout和 mail.smtp.timeout这两个属性分别设置连接超时和读超时。That's all,才怪。因为我这么做可耻地失败了,还是需要等待5分钟才抛出异常。我不生产答案,我是stackoverflow的搬运工: 《Why JavaMail connection timeout is too long》。简单说:那是因为使用的javamail版本太低(开头使用的是1.4),下载最新版(1.5)的javamail jar替换后就可以了。所以如果发现那两个属性设置没有效果,检查一下使用的javamail版本。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!