2008-10-27 62 views
4

我正在使用javax.mail系统,并遇到“无效地址”异常的问题。这里的代码的基础知识:当地址正常时,使用javax.mail获取无效地址

// 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()); 

    } 

问题是,上面的代码有时工作,有时。但对于某些我知道有效的电子邮件地址(因为我可以通过标准的电子邮件客户端发送给他们),上述代码在尝试发送时会引发“无效地址”异常。

任何线索或提示将不胜感激。

- 更新:验证问题。

好的,这是我发现的事情。在接收电子邮件时,上面的代码正确设置了身份验证,并且实际调用了Authenticator.getPasswordAuthentication()回调。

发送电子邮件时并非如此。你必须做更多。加入:

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

这将强制javax.mail API执行登录验证。然后用一个实际的交通情况,而不是静态的。发送()方法:

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){ 

而不强制认证,邮件服务器看到我作为一个未经授权的中继,和把我关闭。 “工作”的地址与没有“工作”的地址之间的差别都是邮件服务器本地的。因此,它只是接受它们。但对于任何非本地“中继”地址,它会拒绝该消息,因为我认为它没有javax.mail API提供的身份验证信息。

感谢您的线索,以提示我也看看邮件服务器的一面。

+0

这将有助于了解报告为无效的电子邮件地址的一些示例。或者至少是他们的格式。 – 2008-10-27 15:08:59

回答

5

--update的位置:问题认证。

好的,这是我发现的事情。在接收电子邮件时,上面的代码正确设置了身份验证,并且实际调用了Authenticator.getPasswordAuthentication()回调。

发送电子邮件时并非如此。你必须做更多。加入:

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

这将强制javax.mail API执行登录验证。然后用一个实际的交通情况,而不是静态的。发送()方法:

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){ 

而不强制认证,邮件服务器看到我作为一个未经授权的中继,和把我关闭。 “工作”的地址与没有“工作”的地址之间的差别都是邮件服务器本地的。因此,它只是接受它们。但对于任何非本地“中继”地址,它会拒绝该消息,因为我认为它没有javax.mail API提供的身份验证信息。

感谢您的线索,以提示我也看看邮件服务器的一面。

0

试试这个:

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); 

对不起,我的英语水平。这不好。

2

我会改变对InternetAddress的调用,以使用“严格”的解释,看看你是否遇到问题的地址进一步错误。

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

Javadoc for InternetAddress constructor

如果失败,它会抛出AddressException,其具有称为getPos()方法,该方法返回失败(Javadoc

0

在我看来,这似乎是我工作中发生的问题。 如果您显示的代码是并发的,那么直接使用System.getProperties 可能会造成问题,因为您放在它们上的主机值可能会被下一个请求覆盖,同时仍然保留覆盖主机的用户和密码。

在我们的例子中,我们解决了使用System.getProperties()哈希表的克隆。

希望有帮助(这个问题真的很难追踪)。

1

一个好线索使用SSL加密在SMTP配置那些,应该通过指定属性mail.smtp.ssl.enable启用,如下图所示:

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

否则如上所述它可以导致类似的问题。