我有java代码用于从Outlook Exchange Server下载邮件。 我面临的问题是:如果互联网连接中断,程序执行将停止。
我希望代码检查互联网连接,直到连接可用。如果互联网断开,我不希望执行停止。
很少有用于检查互联网连接的解决方案是否存在堆栈溢出,但如果我使用这些解决方案,一段时间后我会收到堆栈溢出错误。
private static void checkNetConnectivity()
{
Socket sock = new Socket();
InetSocketAddress addr = new InetSocketAddress("www.google.com",80);
try{
sock.connect(addr,3000);
System.out.println("connected");
}catch(Exception e){
System.out.println("not connected");
}
}
我从以下函数调用该方法:
public static void downloadEmails(String protocol, String host, String port, String username, String password)
{
Properties props = new Properties();
Folder inbox = null;
MimeBodyPart bp = null;
String mail_subject = null, mail_body = null;
int i;
props.setProperty("mail.store.protocol", "imaps");
//props.put("mail.pop3.host", host);
//props.put("mail.pop3.port", port);
//props.put("mail.pop3.starttls.enable", "true");
try
{
do
{
checkNetConnectivity();
Session session = Session.getInstance(props);
//session.setDebug(true);
Store store = session.getStore(protocol);
store.connect(host, username, password);
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);// READ_WRITE mode is compulsory if you want to set the SEEN flag.
cnt = 0;
Flags seen = new Flags(Flags.Flag.SEEN);
FlagTerm unseenFlagTerm = new FlagTerm(seen, false);
Message msg[] = inbox.search(unseenFlagTerm);
System.out.println("No of unseen messages : " + msg.length);
if (msg.length > 0)
{
for (i = 0; i < msg.length; i++)
{
System.out.println("Serial No :" + i);
Address[] in = msg[i].getFrom();
for (Address address : in)
{
System.out.println("FROM:" + address.toString());
//String mail_address = address.toString();
}
System.out.println("SENT DATE: " + msg[i].getSentDate());
System.out.println("SUBJECT: " + msg[i].getSubject());
mail_subject = msg[i].getSubject();
Date date = msg[i].getSentDate();
DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String mail_sent_date = df.format(date);
System.out.println("Sent date = "+ mail_sent_date);
String str1[] = mail_subject.split("\\|");
int sub_delimiter_count = str1.length - 1; //count of delimiter for validating email subject
if (str1[0].equals("1001") && sub_delimiter_count == 3 )
{
System.out.println("Subject line valid.");
Object content = msg[i].getContent();
if (content instanceof String)
{
String body = (String) content;
mail_body = body;
boolean isValid = new ReadMail().ValidateMail(mail_body);
if(isValid)
{
System.out.println("Email body in proper format.");
}
else
{
System.out.println("Email not in proper format.\nIgnoring...");
continue;
}
}
else if (content instanceof Multipart)
{
System.out.println("This is MultiPart");
MimeMultipart mp = (MimeMultipart) msg[i].getContent();
bp = (MimeBodyPart) mp.getBodyPart(0);
InputStream partInput = bp.getInputStream();
mail_body = new Scanner(partInput, "UTF-8").useDelimiter("\\A").next();
}
System.out.println("hhhh");
ReadEmail(mail_subject, mail_body, mail_sent_date);
}
else
{
System.out.println("Subect not in required format.\nIgnoring...");
}
msg[i].setFlag(Flags.Flag.SEEN, true); // for this to work INBOX or any FOLDER has to opened in READ_WRITE mode.
}
} else {
Date date = new Date();
System.out.println("No new messages. Last checked: "+date.toString());
}
try {
Thread.sleep(2000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
store.close();
}while(true);
}catch(Exception e)
{
e.printStackTrace();
//downloadEmails(protocol,host,port,username,password);
}
}
这是互联网断线时的例外情况:
javax.mail.MessagingException:没有到主机的路由:connect;嵌套 异常是:java.net.NoRouteToHostException:没有到主机的路由: 连接在 com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:670)DEBUG: setDebug:JavaMail版本1.4.7 DEBUG:getProvider()返回 javax.mail.Provider [STORE,IMAPS,com.sun.mail.imap.IMAPSSLStore,甲骨文] DEBUG IMAPS:mail.imap.fetchsize:16384 DEBUG IMAPS: mail.imap.ignorebodystructuresize:false DEBUG IMAPS: mail.imap.statuscachetimeout:1000 DEBUG IMAPS: mail.imap.appendbuffersize:-1 DEBUG IMAPS:mail.imap.minidletime:10 DEBUG IMAPS:尝试连接到主机“outlook.office365.com”,端口 993,isSSL是真的
at javax.mail.Service.connect(Service.java:295)at javax.mail.Service.connect(Service.java:176)at readmail.ReadMail.downloadEmails(ReadMail.java:200)at readmail.ReadMail.main(ReadMail.java:323)引起: java.net.NoRouteToHostException:没有到主机的路由:connect at java.net.DualStackPlainSocketImpl.connect0(Native Method)at java.net.DualStackPlainSocketImpl.socketConnect(未知来源)at java.net.AbstractPlainSocketImpl.doConnect(未知来源)at java.net.AbstractPlainSocketImpl.connectToAddress(未知来源)at java.net.AbstractPlainSocketImpl.connect(未知来源)at java.net.PlainSocketImpl.connect(未知来源)at java.net.SocksSocketImpl.connect(未知来源)at java.net.Socket.connect(未知来源)at java.net.Socket.connect(未知来源)at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:321) 在com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:237) 在com.sun.mail.iap.Protocol。(Protocol.java:116)at com.sun.mail.imap.protocol.IMAPProtocol。(IMAPProtocol.java:115) at com.sun.mail.imap.IMAPStore.newIMAPProtocol(IMAPStore.java:685) at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:636) ......还有4个
任何帮助将不胜感激。
答案 0 :(得分:0)
根据OP的要求。使用Sarge框架监督重试。
我将您的连接逻辑外部化为MailService类,以便我可以监督它。
public class MailService {
public Store connect(String protocol, String host, String username, String password) throws MessagingException{
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imap");
//props.put("mail.pop3.host", host);
//props.put("mail.pop3.port", port);
//props.put("mail.pop3.starttls.enable", "true");
Session session = Session.getInstance(props);
//session.setDebug(true);
Store store = session.getStore(protocol);
store.connect(host, username, password);
return store;
}
}
然后我更改了您的downloadEmails
实施,以使用MailService
并为Plan
创建Sarge
。
public static void downloadEmails(String protocol, String host, String port, String username, String password) {
Plan failurePlan = new Plan() {
public Directive apply(Throwable failure) {
if (failure instanceof MessagingException) {
// if we failed due to ConnectException, then retry five times over a minute.
if (((MessagingException) failure).getCause() instanceof ConnectException) {
return Directive.Retry(5, Duration.mins(1));
}
}
return Directive.Escalate;
}
};
Sarge sarge = new Sarge();
Folder inbox = null;
MimeBodyPart bp = null;
String mail_subject = null, mail_body = null;
int i;
try {
MailService supervisedMailService = sarge.supervised(MailService.class, failurePlan);
do {
Store store = supervisedMailService.connect(protocol, host, username, password);
inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
// ... yada yada yada ... your code
当抛出ConnectExceptions时,此示例将在一分钟内重试五次。根据需要在计划中添加其他失败/重试案例。
修改强>
我的pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hall</groupId>
<artifactId>sarge</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SargeExample</name>
<description>SargeExample</description>
<dependencies>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>net.jodah</groupId>
<artifactId>sarge</artifactId>
<version>0.3.1</version>
</dependency>
</dependencies>
</project>