1、获取邮件发送结果
网上看大多数例子,都是调用Transport类的sendMessage方法后就收工了。但
sendMessage方法没有返回值的,而且是一个异步的方法(也就是函数调用结束的时候邮件的发送过程并未结束)。我们可以通过
Transport的addTransportListener方法增加邮件发送结果的Listener,Listener
接口有三个方法:
void messageDelivered(TransportEvent arg0);
// 邮件发送成功
void messageNotDelivered(TransportEvent arg0);
// 邮件发送失败
void messagePartiallyDelivere
d(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 messagePartiallyDelivere
d(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版本。