原文: http://www.blogjava.net/hopeshared/archive/2005/11/27/21553.html
这里,我用pop3连126.com的邮箱取到邮件,解析邮件附件。我的工作是取到jpg或gif图片并保存。
说明:这是我的在工作中写的代码,是可用的。但是有部分代码被截取出来,比如有些参数我觉得没有必要,就删除了,没有测试。可能会有bug,但是肯定是小bug。
连接到邮箱:
{
hostname = "pop.126.com";
username = "yourname";
password = "yourpassword";
//set properties
Properties props = System.getProperties();
Session mailsession = Session.getDefaultInstance(props, null);
//不输出debug信息
mailsession.setDebug(false);
// Get a Store object
Store store = mailsession.getStore("pop3"); 1
// Connect
store.connect(hostname,username, password);//连接
//create a message
Message msg = new MimeMessage(mailsession);
//check inbox
Folder folder=store.getFolder("inbox");//打开收件箱
folder.open(Folder.READ_WRITE);//设置权限为读写
int msgNum = folder.getMessageCount();//得到邮件总数
//一次处理9个邮件
for(int i=1;i<(msgNum>10?10:msgNum+1);i++) 2
{
try
{
//循环解析邮件
msg=folder.getMessage(i);
// and now, handle the content
Object o = msg.getContent();
if (msg.isMimeType("multipart/*")) 3
{
Multipart mp = (Multipart)o;
int cnt = mp.getCount();
for ( int j = 0; j < cnt; j++)
{
displayPart(mp.getBodyPart(j));
}
}else{
continue;
}
}catch (Exception e)
{
System.out.println(e);
msg.setFlag(Flags.Flag.DELETED, true); 4
continue;
}
//对已处理的邮件进行删除操作
msg.setFlag(Flags.Flag.DELETED, true); 5
}
//关闭
folder.close(true); 6
store.close(); 7
}
注1:使用的协议是pop3,因为这里不需要发送邮件,只度读取邮件,pop3协议比较简单方便
注2:这个函数没有一次处理所有的邮件,因为没有这个必要。如果需要一次处理所有邮件的话,将for循环的那部分删除就可以了
注3:message的类型可以是text/plain,text/html或者是multipart/*等类型的。但是只有multipart/*才是有附件的邮件。当然,有的邮件系统是将邮件内容作为附件来传递的。
注4:解析邮件的过程中可能会出现异常,比如我碰到的一个很奇怪的异常就是,当part不为null的时候,part.getFileName()抛出为空的异常。如果不捕获这个异常,会出问题,究竟是什么问题,我在注6里讲解。现在,捕获这个异常。这个邮件是有问题的,如果不删除,下次出来还是会抛异常,于是我们给他置一个删除标志。
注5:将已处理的邮件置删除标志。很奇怪,置删除标志的邮件不是被放在了垃圾箱里,而是被彻底删除了,所以用的时候要小心。但是如果继续留在收件箱,下次又会被处理一次
注6:当前面的邮件解析操作正常结束的时候,folder.close(true)会执行。这个时候,才会将刚刚置了删除标志的邮件删除。前面说过异常如果没有被捕获会出问题。这个问题就是,前面的邮件已经处理了,并且置上了删除标志,但是碰到问题邮件的时候抛出异常,没有被及时捕获,于是folder.close(true)不会被执行,那些该删除的邮件就没有删除。那么当你再调用这个connectMail的时候就会重复的处理邮件。我是在servlet里写的定时器来调用这个函数的,当时出问题,于是有的邮件被重复解析了200多次,这是很可怕的数字。
注7:活儿干完了,要关闭连接。解析邮件:
throws Exception
{
String sct = part.getContentType();
if (sct == null)
{
return; 1
}
ContentType ct = new ContentType(sct);
if(ct.getBaseType().equals("image/gif") || ct.getBaseType().equals("image/jpeg") || ct.getBaseType().equals("image/pjpeg") ) 2
{
// generate a url for this part
String s;
if ((s = part.getFileName()) != null)
{
s = MimeUtility.decodeText(s); 3
}
String strType = s.substring(s.lastIndexOf("."));
InputStream is = part.getInputStream();
if(strType.equals(".gif")||strType.equals(".jpg")) 4
{
do your business here!!!
is.close(); 5
}
} 6
}
注1:part.getContentType()说明取不到这个message的类型,直接返回,不需处理
注2:根据我的需求,我只需处理图片类型,也就是说,只要这3种类型的message,其他的都可以忽略
注3:email是遵循一些编码方式的,大部分用的是base64,但是java mail提供解码的工具,这就是MimeUtility.decodeText(s)
注4:再对文件类型做一次判断(其实我觉得是不需要的,但是严整完整一点还是好些)
注5:有的操作系统对InputStram这样的对象有限制,限制同时打开的InputStream个数,例如linux中就有这样的限制。所以在打开了一个InputStream最好关闭。当然,如果不关闭,java的自动回收功能也回回收这个InputStream
注 6 :其实有的邮件的附件也是 multipart/* 类型的,这时应该再调用 displayPart ,这是这个函数的缺陷,所有注 2 的 if 应该再加一个 else if 调用 displayPart 逻辑上才是正确的