使用JavaMail收取邮件并解析


本文是一个简单的收取邮件的例子。

主要功能是:从服务器收取邮件,然后对邮件进行解析,解析出邮件的发件人、主题、内容、附件等。

使用的类库:JavaMail1.4.7,Apache的commons email1.3.1,另外还有javamail需要依赖jar包:activation.jar

实现过程如下:

1、定义一个简单的邮件收取类,作用连接邮件服务器,然后收取inbox里的邮件,返回Message[]


01 package com.athena.mail.receiver;
02  
03 import java.util.Properties;
04  
05 import javax.mail.Authenticator;
06 import javax.mail.Folder;
07 import javax.mail.Message;
08 import javax.mail.MessagingException;
09 import javax.mail.NoSuchProviderException;
10 import javax.mail.Session;
11 import javax.mail.Store;
12  
13 /**
14  * 简单的邮件接收类
15  *
16  * @author athena
17  *
18  */
19 public class SimpleMailReceiver {
20  
21     /**
22      * 收取收件箱里的邮件
23      *
24      * @param props
25      *            为邮件连接所需的必要属性
26      * @param authenticator
27      *            用户验证器
28      * @return Message数组(邮件数组)
29      */
30     public static Message[] fetchInbox(Properties props, Authenticator authenticator) {
31         return fetchInbox(props, authenticator, null);
32     }
33  
34     /**
35      * 收取收件箱里的邮件
36      *
37      * @param props
38      *            收取收件箱里的邮件
39      * @param authenticator
40      *            用户验证器
41      * @param protocol
42      *            使用的收取邮件协议,有两个值"pop3"或者"imap"
43      * @return Message数组(邮件数组)
44      */
45     public static Message[] fetchInbox(Properties props, Authenticator authenticator, String protocol) {
46         Message[] messages = null;
47         Session session = Session.getDefaultInstance(props, authenticator);
48         // session.setDebug(true);
49         Store store = null;
50         Folder folder = null;
51         try {
52             store = protocol == null || protocol.trim().length() == 0 ? session.getStore() : session.getStore(protocol);
53             store.connect();
54             folder = store.getFolder("INBOX");// 获取收件箱
55             folder.open(Folder.READ_ONLY); // 以只读方式打开
56             messages = folder.getMessages();
57         catch (NoSuchProviderException e) {
58             e.printStackTrace();
59         catch (MessagingException e) {
60             e.printStackTrace();
61         }
62         return messages;
63     }
64 }
2、定义一个邮件解析类,用来解析上面返回的Message[]



01 package com.athena.mail.receiver;
02  
03 import java.io.BufferedInputStream;
04 import java.io.BufferedOutputStream;
05 import java.io.File;
06 import java.io.FileOutputStream;
07 import java.util.List;
08  
09 import javax.activation.DataSource;
10 import javax.mail.Address;
11 import javax.mail.Folder;
12 import javax.mail.Message;
13 import javax.mail.MessagingException;
14 import javax.mail.Store;
15 import javax.mail.internet.MimeMessage;
16  
17 import org.apache.commons.mail.util.MimeMessageParser;
18  
19 /**
20  * 邮件解析类
21  *
22  * @author athena
23  *
24  */
25 public class MessageParser {
26     /**
27      * 邮件附件存放位置
28      */
29     private static final String folder = "D:\\upload";
30  
31     private static void parse(Message message) {
32         try {
33             MimeMessageParser parser = new MimeMessageParser((MimeMessage) message).parse();
34             String from = parser.getFrom(); // 获取发件人地址
35             List<Address> cc = parser.getCc();// 获取抄送人地址
36             List<Address> to = parser.getTo(); // 获取收件人地址
37             String replyTo = parser.getReplyTo();// 获取回复邮件时的收件人
38             String subject = parser.getSubject(); // 获取邮件主题
39             String htmlContent = parser.getHtmlContent(); // 获取Html内容
40             String plainContent = parser.getPlainContent(); // 获取纯文本邮件内容(注:有些邮件不支持html)
41  
42             System.out.println(subject);
43  
44             List<DataSource> attachments = parser.getAttachmentList(); // 获取附件,并写入磁盘
45             for (DataSource ds : attachments) {
46                 BufferedOutputStream outStream = null;
47                 BufferedInputStream ins = null;
48                 try {
49                     String fileName = folder + File.separator + ds.getName();
50                     outStream = new BufferedOutputStream(new FileOutputStream(fileName));
51                     ins = new BufferedInputStream(ds.getInputStream());
52                     byte[] data = new byte[2048];
53                     int length = -1;
54                     while ((length = ins.read(data)) != -1) {
55                         outStream.write(data, 0, length);
56                     }
57                     outStream.flush();
58                     System.out.println("附件:" + fileName);
59                 finally {
60                     if (ins != null) {
61                         ins.close();
62                     }
63                     if (outStream != null) {
64                         outStream.close();
65                     }
66                 }
67             }
68         catch (Exception e) {
69             e.printStackTrace();
70         }
71     }
72  
73     public static void parse(Message... messages) {
74         if (messages == null || messages.length == 0) {
75             System.out.println("没有任何邮件");
76         else {
77             for (Message m : messages) {
78                 parse(m);
79             }
80             // 最后关闭连接
81             if (messages[0] != null) {
82                 Folder folder = messages[0].getFolder();
83                 if (folder != null) {
84                     try {
85                         Store store = folder.getStore();
86                         folder.close(false);// 参数false表示对邮件的修改不传送到服务器上
87                         if (store != null) {
88                             store.close();
89                         }
90                     catch (MessagingException e) {
91                         // ignore
92                     }
93                 }
94             }
95         }
96  
97     }
98 }

3、可以看到我在第1步的SimpleMailReceiver的方法fetchInbox方法的参数,其中一个是Properties,一个是Authenticator,做个邮件开发的都知道,这里不做解释。

为了方便用户使用,我为多个邮件服务器的一些基本信息进行了封装,如下:

01 package com.athena.mail.props;
02  
03 import java.util.Properties;
04  
05 /**
06  * 服务器种类:提供了网易和腾讯的企业邮箱(这两种已经测试通过),和谷歌(测试未通过) 后期有需要可以扩展
07  *
08  * @author athena
09  */
10 public enum HostType {
11  
12     NETEASE {
13         @Override
14         public Properties getProperties() {
15             Properties defaults = new Properties();
16             defaults.put("mail.pop3.host""pop.163.com");
17             defaults.put("mail.imap.host""imap.163.com");
18             defaults.put("mail.store.protocol""pop3"); // 默认使用pop3收取邮件
19             return defaults;
20         }
21  
22     },
23     TENCENT {
24         @Override
25         public Properties getProperties() {
26             Properties defaults = new Properties();
27             defaults.put("mail.pop3.host""pop.exmail.qq.com");
28             defaults.put("mail.imap.host""imap.exmail.qq.com");
29             defaults.put("mail.store.protocol""pop3"); // 默认使用pop3收取邮件
30             return defaults;
31         }
32     },
33     GMAIL {
34  
35         @Override
36         public Properties getProperties() {
37             Properties defaults = new Properties();
38             defaults.put("mail.pop3.host""pop.gmail.com");
39             defaults.put("mail.pop3.port""995");
40             defaults.put("mail.imap.host""imap.gmail.com");
41             defaults.put("mail.imap.port""465");
42             defaults.put("mail.store.protocol""pop3"); // 默认使用pop3收取邮件
43             return defaults;
44         }
45  
46     };
47  
48     public abstract Properties getProperties();
49  
50 }
上面类的主要作用是方便用户使用,由于不同邮件服务器使用的地址以及参数都有所不同,而这些信息不会经常变化,所以就无需让用户操作了,用户使用的时候只需要获取她需要的服务器对象即可。

4、对Authenticator也进行了简单封装

01 package com.athena.mail.props;
02  
03 import javax.mail.Authenticator;
04 import javax.mail.PasswordAuthentication;
05  
06 /**
07  * 该类用来生成Authenticator
08  *
09  * @author athena
10  *
11  */
12 public final class AuthenticatorGenerator {
13  
14     /**
15      * 根据用户名和密码,生成Authenticator
16      *
17      * @param userName
18      * @param password
19      * @return
20      */
21     public static Authenticator getAuthenticator(final String userName, final String password) {
22         return new Authenticator() {
23             @Override
24             protected PasswordAuthentication getPasswordAuthentication() {
25                 return new PasswordAuthentication(userName, password);
26             }
27         };
28     }
29  
30 }

最后是一个简单的测试类:

01 package com.athena.mail.client;
02  
03 import com.athena.mail.props.AuthenticatorGenerator;
04 import com.athena.mail.props.HostType;
05 import com.athena.mail.receiver.MessageParser;
06 import com.athena.mail.receiver.SimpleMailReceiver;
07  
08 /**
09  * 邮件测试类
10  *
11  * @author athena
12  *
13  */
14 public class MailTest {
15  
16     public static void main(String[] args) {
17         MessageParser.parse(SimpleMailReceiver.fetchInbox(HostType.NETEASE.getProperties(),
18                 AuthenticatorGenerator.getAuthenticator("youraccount""yourpassword")));
19     }
20 }


后记:

本来对于Properties的封装我采用的继承Properties的方式,如下:

01 package com.athena.mail.props;
02  
03 import java.util.Properties;
04  
05 public class NeteaseProperties extends Properties {
06  
07     private static final long serialVersionUID = -6623862312603756003L;
08  
09     {
10         defaults = new Properties();
11         defaults.put("mail.pop3.host""pop.163.com");
12         defaults.put("mail.imap.host""imap.163.com");
13         defaults.put("mail.store.protocol""pop3"); // 默认使用pop3收取邮件
14     }
15  
16 }
1 即通过在子类中添加一个非静态初始化块(当然,在子类的构造函数中也可以),将Properties类的成员变量defaults进行实例化(Properties将put进去的值都放在defaults变量中)并赋给相应的值。但考虑到如果有很多邮箱的话,类的数量就增加了,而且这样的一种扩展方式也不是很好(原因我也不知道,就是感觉不太好),所以就该成了上面的枚举的方式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值