2008-10-27 4 views
4

J'utilise le système javax.mail et je rencontre des problèmes avec les exceptions "adresse invalide". Voici les bases du code:Obtenir une adresse invalide avec javax.mail lorsque les adresses sont correctes

// Get system properties 
    Properties props = System.getProperties(); 

    // Setup mail server 
    props.put("mail.smtp.host", m_sending_host); 

    // Get session 
    Session session = Session.getDefaultInstance(props, new Authenticator(){ 
     @Override 
     protected PasswordAuthentication getPasswordAuthentication() { 
      return new PasswordAuthentication(m_sending_user, m_sending_pass); 
     } 
    }); 


    // Define message 
    MimeMessage message = new MimeMessage(session); 
    message.setFrom(new InternetAddress(m_sending_from)); 
    message.addRecipient(Message.RecipientType.TO, 
     new InternetAddress(vcea.get(i).emailaddr)); 
    message.setSubject(replaceEnvVars(subject)); 
    message.setText(replaceEnvVars(body)); 

    // Send message 
    try { 
     Transport.send(message); 
    } catch (Exception e){ 
     Log.Error("Error sending e-mail to addr (%s): %s", 
       vcea.get(i).emailaddr, e.getLocalizedMessage()); 

    } 

Le problème est que le code ci-dessus fonctionne, parfois. Mais pour certaines adresses e-mail que je sais être valides (parce que je peux leur envoyer via un client de messagerie standard), le code ci-dessus jettera une exception "Invalid Address" lors de la tentative d'envoi.

Des indices ou des indices seraient grandement appréciés.

--Mise à jour: problème d'authentification.

Ok, voici ce que j'ai découvert qui se passait. Lors de la réception d'un courrier électronique, le code ci-dessus configure correctement l'authentification et le rappel Authenticator.getPasswordAuthentication() est appelé.

Ce n'est pas le cas lors de l'envoi d'un courrier électronique. Vous devez faire un peu plus. Ajoutez ceci:

// Setup mail server 
    props.put("mail.smtp.host", m_sending_host); 
    props.put("mail.smtp.auth", "true"); 

qui force l'API javax.mail à effectuer l'authentification de connexion. Et puis utilisez une instance réelle de transport au lieu de la méthode .send statique():

Transport t = session.getTransport(m_sending_protocol); 
    t.connect(m_sending_user, m_sending_pass); 

...

 // Send message 
     try { 
      t.sendMessage(message, message.getAllRecipients()); 
     } catch (Exception e){ 

Sans forcer l'authentification, le serveur de messagerie m'a vu comme un relais non autorisé, et Fermez-moi. La différence entre les adresses qui "travaillaient" et les adresses qui ne fonctionnaient pas était que celles qui "travaillaient" étaient toutes locales au serveur de messagerie. Par conséquent, il les a simplement acceptés. Mais pour toutes les adresses "relais" non locales, il rejetterait le message car mes informations d'authentification n'avaient pas été présentées par l'API javax.mail quand je pensais que cela aurait été le cas.

Merci pour les indices qui m'incitent à regarder aussi le côté serveur de courrier.

+0

Il serait utile de connaître quelques exemples d'adresses électroniques signalées comme non valides. Ou au moins leur format. –

+0

matt b - ce qu'il a dit! –

+0

Veuillez donner une liste d'emails invalides. – johnstok

Répondre

5

--update: problème avec l'authentification.

Ok, voici ce que j'ai découvert qui se passait. Lors de la réception d'un courrier électronique, le code ci-dessus configure correctement l'authentification et le rappel Authenticator.getPasswordAuthentication() est appelé.

Ce n'est pas le cas lors de l'envoi d'un courrier électronique. Vous devez faire un peu plus.Ajoutez ceci:

// Setup mail server 
props.put("mail.smtp.host", m_sending_host); 
props.put("mail.smtp.auth", "true"); 

qui force l'API javax.mail à effectuer l'authentification de connexion. Et puis utilisez une instance réelle de transport au lieu de la méthode .send statique():

Transport t = session.getTransport(m_sending_protocol); 
t.connect(m_sending_user, m_sending_pass); 

...

// Send message 
    try { 
     t.sendMessage(message, message.getAllRecipients()); 
    } catch (Exception e){ 

Sans forcer l'authentification, le serveur de messagerie m'a vu comme un relais non autorisé, et Fermez-moi. La différence entre les adresses qui "travaillaient" et les adresses qui ne fonctionnaient pas était que celles qui "travaillaient" étaient toutes locales au serveur de messagerie. Par conséquent, il les a simplement acceptés. Mais pour toutes les adresses "relais" non locales, il rejetterait le message car mes informations d'authentification n'avaient pas été présentées par l'API javax.mail quand je pensais que cela aurait été le cas.

Merci pour les indices qui m'incitent à regarder aussi le côté serveur de courrier.

0

Essayez ceci:

String to="[email protected]"; 
String cc="[email protected],[email protected]"; //The separator ',' works good 

message.setRecipients(Message.RecipientType.TO,new InternetAddress[] { 
new InternetAddress(to) }); // This is only one mail 

InternetAddress[] addr = parseAddressList(cc); //Here add all the rest of the mails 
message.setRecipients(Message.RecipientType.CC,addr); 

Désolé pour mon anglais. Ce n'est pas bon.

2

Je voudrais changer l'appel à InternetAddress pour utiliser l'interprétation "stricte" et voir si vous obtenez d'autres erreurs sur les adresses que vous rencontrez des problèmes.

message.addRecipient(Message.RecipientType.TO, 
     new InternetAddress(vcea.get(i).emailaddr, true)); 
//             ^^^^ turns on strict interpretation 

Javadoc for InternetAddress constructor

Si cela échoue, il lancera une AddressException qui a une méthode appelée getPos() qui renvoie la position de l'échec (Javadoc)

0

Cela me semble être un problème qui s'est produit à mon travail. Si le code que vous affichez est concurrent, l'utilisation directe de System.getProperties peut poser un problème, car la valeur d'hôte que vous placez dessus peut être remplacée par la demande suivante, tout en conservant l'utilisateur et le mot de passe de l'hôte remplacé.

Dans notre cas, nous avons résolu cela en utilisant un clone de la hashtable System.getProperties().

Espérons que cela aide (ce problème était vraiment difficile à suivre).

1

Une bonne astuce pour ceux qui utilisent le cryptage SSL dans la configuration de smtp, vous devez activer en spécifiant la propriété mail.smtp.ssl.enable, comme indiqué ci-dessous:

props.put("mail.smtp.ssl.enable", "true"); 

Sinon, il peut conduire à des problèmes similaires à ceux décrits ci-dessus.

Questions connexes