2016-03-22 2 views
1

У меня есть Java-код, с помощью которого я загружаю письма с Outlook Exchange Server. Проблема, с которой я столкнулся: если подключение к Интернету не работает, выполнение программы прекращается.Проверка подключения к Интернету в java

Я хочу, чтобы код проверялся на подключение к интернету до тех пор, пока соединение не будет доступно. Я не хочу, чтобы выполнение остановилось, если интернет отключен.

Несколько решений для проверки подключения к Интернету находятся в переполнении стека, но если я использую это решение, через некоторое время я получу ошибку stackoverflow.

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: Нет маршрута для host: 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, Oracle] 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 true

на javax.mail.Service.connect (Service.java:295) при javax.mail.Service.connect (Service.java:176) при readmail.ReadMail.downloadEmails (ReadMail.java:200) в readmail.ReadMail.main (ReadMail.java:323) Вызвано: java.net.NoRouteToHostException: нет маршрута к хосту: подключитесь к java.net.DualStackPlainSocketImpl.connect0 (собственный метод) в java.net.DualStackPlainSocketImpl.socketConnect (Unknown Source) на java.net.AbstractPlainSocketImpl.doConnect (Unknown Source) в java.net.AbstractPlainSocketImpl.connectToAddress (Unknown Source) в java.net.AbstractPlainSocketImpl.connect (Unknown Source) в java.net.PlainSo cketImpl.connect (Неизвестный источник) на java.net.SocksSocketImpl.connect (Неизвестный источник) на java.net.Socket.connect (Неизвестный источник) на java.net.Socket.connect (Неизвестный источник) на com. sun.mail.util.SocketFetcher.createSocket (SocketFetcher.java:321) на com.sun.mail.util.SocketFetcher.getSocket (SocketFetcher.java:237) на com.sun.mail.iap.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 еще

Любая помощь будет принята с благодарностью.

+1

показывают, что решение, и мы поможем вам ... – epoch

+2

'StackOverflowError', скорее всего, произойдет в неконтролируемых рекурсивных вызовов, поэтому анализ кода, чтобы увидеть где может случиться –

+0

Что вы подразумеваете под «остановкой программы»? Сбой приложения? Если да, то какое исключение вы видите? – Alex

ответ

0

По запросу ОП. Наблюдение за повторениями с использованием 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. При необходимости добавьте другие случаи отказов/повторов в план.

Редактировать

Мой ПОМ

<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> 
+0

Я внесла изменения в код, но я не могу запустить код .. есть ли какая-либо конфигурация, которая должна быть сделана для sarge? Поскольку я новичок в этом, я понятия не имею, что делать. может у, пожалуйста, помогите. –

+0

Я добавил моего Maven pom. Maven загрузит зависимости, необходимые для компиляции и запуска. Если вы не используете Maven или Gradle, я призываю вас потратить время, чтобы создать базовое представление о том, как его использовать. – MarkOfHall

Смежные вопросы