通过JavaMail访问Hotmail邮箱

红薯 发布于 2008/10/05 16:58
阅读 2K+
收藏 0

相信许多人都有MSN聊天工具的帐号,例如abc@hotmail.com ,这个账号其实也是一个邮件地址,可以进行正常的邮件收发功能,你可以通过网址 http://www.hotmail.com 来访问和操作这个邮箱进行邮件的收发。但是这个邮箱有一个限制就是它并不提供POP3或者SMTP服务,也就是说一般的邮件客户端工具无法使用这个邮箱, 虽然现在有不少的邮件工具可以支持Hotmail邮箱,但是如果我们需要在我们的Java项目中增加对Hotmail邮箱的支持,那往往会不知从什么地方 开始入手,因为SUN公司提供的JavaMail 本身并不提供对除了POP3/IMAP以及SMTP外其他协议的支持。

但事实上,JavaMail只是定义了一组平台无关、独立于通讯协议的邮件程序框架,或者说是接口,它是作为Java的可选包存在的。因此可以这样 说:JavaMail并不关心所使用的协议,不管是POP3、SMTP、IMAP当然还有Hotmail用的HTTP协议。对于JavaMail的客户端 而言也是这样的,下图就是一个最简单的JavaMail结构图,通过Transport进行邮件的发送,通过Store实现对邮件的收取,而不同协议的实 现,JavaMail里的概念叫做Provider,只需要根据JavaMail定义的接口实现自己的Provider即可。


为了实现通过JavaMail访问Hotmail邮箱,我们就需要架起JavaMail接口与Hotmail服务所提供的访问接口之间 的桥梁。在这之前我们必须首先了解Hotmail所使用的接口协议。

Hotmail 通过地址 http://services.msn.com/svcs/hotmail/httpmail.asp 提供基于 HTTP 协议的服务,它不同于我们通过浏览器访问 http://www.hotmail.com的这个地 址,后面这个地址是提供给用户一个基于浏览器的访问界面以便对邮箱进行操作,你当然可以通过编写HTTP客户端程序来解析页面并获取邮件的信息,但是这样 做不仅实现的复杂程度非常高,而且每次页面风格发生变化后程序都要做相应的调整,因此不具备通用性,显然是不可行的。而地址 http://services.msn.com/svcs/hotmail/httpmail.asp 则不同,它提供了固定的应用程序接口。当你使用浏览器访问该地址的时候,会弹出下面要求登录的窗体:


而当输入正确的用户名和口令后会再弹出一次或两次该提示窗口,但提示信息不同,操作完成后出现页面无法显示的错误,错误码是 405 (资源不允许)。因此该服务并不允许通过浏览器来访问。

事实上Hotmail使用的是WebDAV来提供基于HTTP协议的应用编程接口,WebDAV(Web 分布式创作和版本控制)已经成为重要的 Web 通讯协议。WebDAV所要解决的问题是:

1.改写保护:HTTP 1.1 无法确保客户端可以保护资源,并且可以在其他客户端同时编辑它们的情况下进行更改。 使用 WebDAV,可以通过多种方式来锁定资源,以便让其他客户端知道您对所讨论的资源感兴趣,或者防止其他客户端访问该资源。

2.资源管理:HTTP 只能直接访问单个资源。 WebDAV 提供一种更有效地组织数据的方法。 WebDAV 引入了可包含资源 的集合(类似于文件系统文件夹)概念。 通过 WebDAV 进行的资源管理包括如下功能:创建、移动、复制和删除集合,以及集合中的资源或文件。

3.文档属性:不同类型的数据具有唯一的属性,这有助于描述数据。 例如,在电子邮件中,这些属性可能是发件人的姓名和接收邮件的时间。 在协作文档中,这些属性可能是文档原始作者的姓名和最后一个编辑者的姓名。 因为人们使用的文档类型各不相同,所以可能的属性类型列表也变得无限大。 XML 是 WebDAV 所需的一种可扩展通讯工具。

关于WebDAV的更多资料可以参阅本文最后的参考资料。

相对于自行解析Hotmail的浏览器页面而言,基于特定协议WebDAV的接口使Hotmail邮件客户端程序的实现更加稳定和可 靠。在了解了JavaMail API的基本接口以及Hotmail所提供接口的协议,本文的题目就变得非常具体了,就是如果编写基于WebDAV的JavaMail Provider(JavaMail提供者)并使用这个提供者来实现Hotmail邮件收发功能,但这题目太大而且已经超过了一篇文章所能叙述的范围,因 此我们接下来将引入一个开放源码项目JDAVMail,并详细介绍如何通过这个项目实现Hotmail邮件的收发功能。

JDAVMail 是一个开放源码的JavaMail的提供者项目,可以通过它来访问基于WebDAV协议的邮件服务,有如Hotmail邮箱。你可以到 http://sourceforge.net/projects/jdavmail这 个网址下载到最新版本的程序。JDAVMail使用了Jakarta上的commons httpclient 作为HTTP客户端组件与服务器进行通讯,同时使用了jdom进行XML数据的解析,另外由于httpclient项目用到了commons logging进行日记的输出,因此commons-logging也是必须的,这三个组件都可以在JDAVMail的压缩包中的lib目录中找到,压缩 包中同时还包括已编译的jar文件以及所有的源码。

为了让大家对JDAVMail有个大概的认识,下面我们给出两段代码用于Hotmail邮件的收发:

1. 邮件收取

/*
* 文件名:HotmailDemo.java
* 创建时间:2004-9-14
* 创建者:liudong
*/
package com.clickcom.mail;
import java.util.Date;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
* Hotmail邮件的收发器
* @author liudong
*/
public class HotmailDemo {
public static void main(String[] args) {
receive();
}
/**
* 邮件接收
*/
protected static void receive() {
try {
Properties prop = new Properties();
Session ses = Session.getInstance(prop);
//使用JDAVMail Provider


Store store = ses.getStore("davmail");
//无需指定服务器地址
store.connect(null, "

你的帐号","

密码");
if (store.isConnected()) {
Folder inbox = store.getFolder("INBOX");
if (inbox.exists()) {
inbox.open(Folder.READ_ONLY);
int nCount = inbox.getMessageCount();
System.out.println("Inbox contains " + nCount + " messages");
// 依次显示收件箱中的每封邮件
for(int i=1;i<=nCount;i++){
MimeMessage msg = (MimeMessage) inbox.getMessage(i);
System.out.println("Subject : " + msg.getSubject());
System.out.println("From : " + msg.getFrom()[0].toString());
System.out.println("Content type : " + msg.getContentType());
System.out.println(msg.getContent());
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

 

从上面这段代码我们发现除了 Store store = ses.getStore("davmail");这个语句,同时不需要指定服务器地址外, 其他的都跟一个普通的JavaMail应用程序没有两样,也没有引入任何跟JDAVMail有关的类。没有指定服务器地址这个比较容易理解,因为 Hotmail提供HttpMail服务的地址是固定的。事实上仅有getStore这个语句跟常规邮件客户端程序有点不同的是它使用davmail字符 串作为参数,而我们在使用JavaMail连接POP3服务器的时候指定参数值为pop3。怎么回事呢?因为JavaMail是通过协议名来加载 Provider类的。打开JDAVMail.0.9.006.jar这个jar文件就会发现在META-INF目录下有一个文件 javamail.providers,该文件内容如下:

protocol=davmail; type=store; class=com.posisoft.jdavmail.JDAVMailStore; vendor=Positive Software;
protocol=davmail_xmit; type=transport; class=com.posisoft.jdavmail.JDAVMailTransport; vendor=Positive Software;

 

因此当我们指定协议名为davmail时,JavaMail就会自动加载 com.posisoft.jdavmail.JDAVMailStore类进行处理,因此通过传入davmail字符串所得到的store实例实际上是 类com.posisoft.jdavmail.JDAVMailStore的一个实例,这样我想大家应该了解了前面这段程序的工作原理。

我们再来看JDAVMail发送邮件的代码片段:

/**
* 邮件发送
*/
protected static void send() {
try {
Properties prop = new Properties();
//邮件发送者地址
prop.setProperty("mail.davmail.from","abc@hotmail.com");
Session ses = Session.getInstance(prop);
//获得JDAVMail的邮件发送实例


Transport transport = ses.getTransport("davmail_xmit");
//连接到Hotmail服务器,请替换为自己的用户名和口令
transport.connect(null, "

用户名","

口令");
// 准备要发送的邮件
MimeMessage txMsg = new MimeMessage(ses);
txMsg.setSubject("This is the subject");
//邮件发送者地址
InternetAddress addrFrom = new InternetAddress("abc@hotmail.com");
txMsg.setFrom(addrFrom);
//邮件接收者地址
InternetAddress addrTo = new InternetAddress("cdef@hotmail.com", "cdef");
txMsg.addRecipient(Message.RecipientType.TO, addrTo);
//邮件内容
txMsg.setText("Hello world !");
txMsg.setSentDate(new Date());
//发送邮件
transport.sendMessage(txMsg, txMsg.getAllRecipients());
} catch (Exception ex) {
ex.printStackTrace();
}
}

 

同样这段代码使用了davmail_xmit协议来获取JDAVMail的邮件发送实例,通过前面提到的 javamail.providers文件不难知道JDAVMail使用类 com.posisoft.jdavmail.JDAVMailTransport进行邮件的发送处理。

在实际测试中发现不管是JDAVMail还是其他的邮件工具,使用Hotmail进行邮件的发送速度比较慢,差不多有几分钟后才能收到 相应的信息,因此如果测试中发现该问题请耐心等待。

我想通过本文介绍如何利用JDAVMail收发Hotmail邮件,以及研究JDAVMail的源码,不仅可以更加深入了解 JavaMail的体系结构,对编写JavaMail Provider也有更加具体的参照。另外希望为正困挠于如何在Java程序中访问Hotmail邮件的朋友们排忧解难。同时也非常欢迎通过我的网站 http://www.javayou.com跟我交流在 使用中遇到的问题。

加载中
0
c
c363535948

我参考了下你的代码,然后加了SSL安全连接出错了,不加也错:如下

package mail;

import java.util.Date;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
//import org.springframework.mail.javamail.JavaMailSenderImpl;

public class TestMail {
 public static void main(String[] args){
  String mailbody = "http://www.laabc.com 用户邮件注册测试 <font color=red>欢迎光临</font> <a href=\"http://user.qzone.qq.com/363535948/infocenter\">啦ABC</a>";
  int testresult = 0;// 定义邮件返回结果,1:成功 0:失败
  String testemail="chenling0116@163.com";
   String smtpAddress = "smtp.live.com";
   String smtpUser = "chenling0116@hotmail.com";
   String smtpPort = String.valueOf(25);
   final String username = "chenling0116@hotmail.com";
   final String password = "******";
   int link=1;
    try {
     Properties prop = new Properties(); //邮件发送者地址  
     prop.put("mail.smtp.host",smtpAddress);
     String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
     prop.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
     prop.setProperty("mail.smtp.socketFactory.fallback", "false");
     prop.setProperty("mail.smtp.socketFactory.port", smtpPort);
     prop.setProperty("mail.smtp.ssl","true");
     prop.setProperty("mail.davmail.from",smtpUser);   
     prop.setProperty("mail.smtp.auth", "false");
     prop.setProperty("mail.debug", "true");
     Session ses = Session.getInstance(prop);   
     //获得JDAVMail的邮件发送实例                  
     Transport transport = ses.getTransport("davmail_xmit"); 
     //连接到Hotmail服务器,请替换为自己的用户名和口令   
     transport.connect(smtpAddress,smtpUser,password);   
    
     
     // 准备要发送的邮件   
     MimeMessage txMsg = new MimeMessage(ses);   
     txMsg.setSubject("This is the subject");   //邮件发送者地址   
     InternetAddress addrFrom = new InternetAddress(smtpUser);   
     txMsg.setFrom(addrFrom);   //邮件接收者地址   
     InternetAddress addrTo = new InternetAddress(testemail);   
     txMsg.addRecipient(Message.RecipientType.TO, addrTo);   //邮件内容   
     txMsg.setText("Hello world !");   
     txMsg.setSentDate(new Date());   //发送邮件   
     transport.sendMessage(txMsg, txMsg.getAllRecipients());  
     }
    catch (Exception ex) {
      ex.printStackTrace();  
      }

   } 

}   
   
   
   
   
   

DEBUG: JavaMail version 1.4.1ea-SNAPSHOT
DEBUG: not loading file: D:\Program Files\MyEclipse 6.5\jre\lib\javamail.providers
DEBUG: java.io.FileNotFoundException: D:\Program Files\MyEclipse 6.5\jre\lib\javamail.providers (系统找不到指定的文件。)
DEBUG: URL jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/JDAVMail/JDAVMail.0.9.006.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: jar:file:/C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/JDAVMail/JDAVMail.0.9.006.jar!/META-INF/javamail.providers
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.posisoft.jdavmail.JDAVMailTransport=javax.mail.Provider[TRANSPORT,davmail_xmit,com.posisoft.jdavmail.JDAVMailTransport,Positive Software], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], com.posisoft.jdavmail.JDAVMailStore=javax.mail.Provider[STORE,davmail,com.posisoft.jdavmail.JDAVMailStore,Positive Software]}
DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], davmail=javax.mail.Provider[STORE,davmail,com.posisoft.jdavmail.JDAVMailStore,Positive Software], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], davmail_xmit=javax.mail.Provider[TRANSPORT,davmail_xmit,com.posisoft.jdavmail.JDAVMailTransport,Positive Software], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: !anyLoaded
DEBUG: not loading resource: /META-INF/javamail.address.map
DEBUG: not loading file: D:\Program Files\MyEclipse 6.5\jre\lib\javamail.address.map
DEBUG: java.io.FileNotFoundException: D:\Program Files\MyEclipse 6.5\jre\lib\javamail.address.map (系统找不到指定的文件。)
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,davmail_xmit,com.posisoft.jdavmail.JDAVMailTransport,Positive Software]
log4j:WARN No appenders could be found for logger (org.apache.commons.httpclient.params.DefaultHttpParams).
log4j:WARN Please initialize the log4j system properly.
javax.mail.MessagingException: protocolConnect exception;
  nested exception is:
 java.net.ProtocolException: HTTP: status code 504
 at com.posisoft.jdavmail.JDAVMailService.protocolConnect(JDAVMailService.java:179)
 at com.posisoft.jdavmail.JDAVMailTransport.protocolConnect(JDAVMailTransport.java:76)
 at javax.mail.Service.connect(Service.java:288)
 at javax.mail.Service.connect(Service.java:169)
 at mail.TestMail.main(TestMail.java:40)
Caused by: java.net.ProtocolException: HTTP: status code 504
 at com.posisoft.jdavmail.JDAVMailService.executeMethod(JDAVMailService.java:223)
 at com.posisoft.jdavmail.JDAVMailService.updateFoldersInfo(JDAVMailService.java:243)
 at com.posisoft.jdavmail.JDAVMailService.protocolConnect(JDAVMailService.java:173)
 ... 4 more

0
阿仁,这么多兄弟我最信你了
阿仁,这么多兄弟我最信你了

我也参考了前辈的代码,访问hotmail,也有问题。Properties prop = new Properties();
        Session ses = Session.getInstance(prop);
        Store store = ses.getStore("davmail");
        store.connect(null,xxx@hotmail.com",xxx");
        Folder inbox = store.getFolder("INBOX");
        if(inbox.exists()){
         inbox.open(Folder.READ_ONLY);
            int nCount = inbox.getMessageCount();
            System.out.println("Inbox contains " + nCount + " messages");
            // ...etc
        }

但还是验证不过去,是不是还有别的方面的认证。

错误码如下:

javax.mail.AuthenticationFailedException

望前辈帮忙分析一下哈,多谢了。

0
红薯
红薯

引用来自#3楼“岁月如歌____”的帖子

我也参考了前辈的代码,访问hotmail,也有问题。Properties prop = new Properties();
        Session ses = Session.getInstance(prop);
        Store store = ses.getStore("davmail");
        store.connect(null,xxx@hotmail.com",xxx");
        Folder inbox = store.getFolder("INBOX");
        if(inbox.exists()){
         inbox.open(Folder.READ_ONLY);
            int nCount = inbox.getMessageCount();
            System.out.println("Inbox contains " + nCount + " messages");
            // ...etc
        }

但还是验证不过去,是不是还有别的方面的认证。

错误码如下:

javax.mail.AuthenticationFailedException

望前辈帮忙分析一下哈,多谢了。

不要试了,hotmail已经关闭此功能N年了。

0
阿仁,这么多兄弟我最信你了
阿仁,这么多兄弟我最信你了

那用javamail就无法连接hotmail了?

0
红薯
红薯

引用来自#5楼“岁月如歌____”的帖子

那用javamail就无法连接hotmail了?

不知道hotmail现在有没有提供pop3或者是imap的访问方式。

0
阿仁,这么多兄弟我最信你了
阿仁,这么多兄弟我最信你了

恩,那OE、foxmail之类的是通过什么渠道都的呢,应该一样吧,他们都能连接,javamail没理由啊

0
紅顏為君笑
紅顏為君笑
pop3 和  imap 连接都会报 AuthenticationFailedException 纠结中
紅顏為君笑
紅顏為君笑
回复 @红薯 : 呜呜 谢谢提醒!
红薯
红薯
请看评论哦,hotmail已关闭此功能多年:)
返回顶部
顶部