本文是一个简单的收取邮件的例子。
主要功能是:从服务器收取邮件,然后对邮件进行解析,解析出邮件的发件人、主题、内容、附件等。
使用的类库:JavaMail1.4.7,Apache的commons email1.3.1,另外还有javamail需要依赖jar包:activation.jar
实现过程如下:
1、定义一个简单的邮件收取类,作用连接邮件服务器,然后收取inbox里的邮件,返回Message[]
01 |
package com.athena.mail.receiver; |
03 |
import java.util.Properties; |
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; |
19 |
public class SimpleMailReceiver
{ |
26 |
*
@param authenticator |
28 |
*
@return Message数组(邮件数组) |
30 |
public static Message[]
fetchInbox(Properties props, Authenticator authenticator) { |
31 |
return fetchInbox(props,
authenticator, null ); |
39 |
*
@param authenticator |
42 |
*
使用的收取邮件协议,有两个值"pop3"或者"imap" |
43 |
*
@return Message数组(邮件数组) |
45 |
public static Message[]
fetchInbox(Properties props, Authenticator authenticator, String protocol) { |
46 |
Message[]
messages = null ; |
47 |
Session
session = Session.getDefaultInstance(props, authenticator); |
52 |
store
= protocol == null ||
protocol.trim().length() == 0 ?
session.getStore() : session.getStore(protocol); |
54 |
folder
= store.getFolder( "INBOX" ); |
55 |
folder.open(Folder.READ_ONLY); |
56 |
messages
= folder.getMessages(); |
57 |
} catch (NoSuchProviderException
e) { |
59 |
} catch (MessagingException
e) { |
2、定义一个邮件解析类,用来解析上面返回的Message[]
01 |
package com.athena.mail.receiver; |
03 |
import java.io.BufferedInputStream; |
04 |
import java.io.BufferedOutputStream; |
06 |
import java.io.FileOutputStream; |
07 |
import java.util.List; |
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; |
17 |
import org.apache.commons.mail.util.MimeMessageParser; |
25 |
public class MessageParser
{ |
29 |
private static final String
folder = "D:\\upload" ; |
31 |
private static void parse(Message
message) { |
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(); |
40 |
String
plainContent = parser.getPlainContent(); |
42 |
System.out.println(subject); |
44 |
List<DataSource>
attachments = parser.getAttachmentList(); |
45 |
for (DataSource
ds : attachments) { |
46 |
BufferedOutputStream
outStream = null ; |
47 |
BufferedInputStream
ins = null ; |
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 ]; |
54 |
while ((length
= ins.read(data)) != - 1 )
{ |
55 |
outStream.write(data, 0 ,
length); |
58 |
System.out.println( "附件:" +
fileName); |
63 |
if (outStream
!= null )
{ |
68 |
} catch (Exception
e) { |
73 |
public static void parse(Message...
messages) { |
74 |
if (messages
== null ||
messages.length == 0 )
{ |
75 |
System.out.println( "没有任何邮件" ); |
77 |
for (Message
m : messages) { |
81 |
if (messages[ 0 ]
!= null )
{ |
82 |
Folder
folder = messages[ 0 ].getFolder(); |
85 |
Store
store = folder.getStore(); |
90 |
} catch (MessagingException
e) { |
3、可以看到我在第1步的SimpleMailReceiver的方法fetchInbox方法的参数,其中一个是Properties,一个是Authenticator,做个邮件开发的都知道,这里不做解释。
为了方便用户使用,我为多个邮件服务器的一些基本信息进行了封装,如下:
01 |
package com.athena.mail.props; |
03 |
import java.util.Properties; |
06 |
*
服务器种类:提供了网易和腾讯的企业邮箱(这两种已经测试通过),和谷歌(测试未通过) 后期有需要可以扩展 |
10 |
public enum HostType
{ |
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" ); |
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" ); |
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" ); |
48 |
public abstract Properties
getProperties(); |
上面类的主要作用是方便用户使用,由于不同邮件服务器使用的地址以及参数都有所不同,而这些信息不会经常变化,所以就无需让用户操作了,用户使用的时候只需要获取她需要的服务器对象即可。
4、对Authenticator也进行了简单封装
01 |
package com.athena.mail.props; |
03 |
import javax.mail.Authenticator; |
04 |
import javax.mail.PasswordAuthentication; |
12 |
public final class AuthenticatorGenerator
{ |
15 |
*
根据用户名和密码,生成Authenticator |
21 |
public static Authenticator
getAuthenticator( final String
userName, final String
password) { |
22 |
return new Authenticator()
{ |
24 |
protected PasswordAuthentication
getPasswordAuthentication() { |
25 |
return new PasswordAuthentication(userName,
password); |
最后是一个简单的测试类:
01 |
package com.athena.mail.client; |
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; |
14 |
public class MailTest
{ |
16 |
public static void main(String[]
args) { |
17 |
MessageParser.parse(SimpleMailReceiver.fetchInbox(HostType.NETEASE.getProperties(), |
18 |
AuthenticatorGenerator.getAuthenticator( "youraccount" , "yourpassword" ))); |
后记:
本来对于Properties的封装我采用的继承Properties的方式,如下:
01 |
package com.athena.mail.props; |
03 |
import java.util.Properties; |
05 |
public class NeteaseProperties extends Properties
{ |
07 |
private static final long serialVersionUID
= -6623862312603756003L; |
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" ); |
1 |
即通过在子类中添加一个非静态初始化块(当然,在子类的构造函数中也可以),将Properties类的成员变量defaults进行实例化(Properties将put进去的值都放在defaults变量中)并赋给相应的值。但考虑到如果有很多邮箱的话,类的数量就增加了,而且这样的一种扩展方式也不是很好(原因我也不知道,就是感觉不太好),所以就该成了上面的枚举的方式 |