邮件

基于Javamail构建邮件客户端的简单实现

2017-01-17  本文已影响0人  BigBug77
背景

近期需要实现一个邮件客户端的项目,类似Foxmail,outlook客户端。但项目只做消息转发,不需要完整实现。

邮件协议

常用的电子邮件协议有SMTP、POP3、IMAP4,它们都隶属于TCP/IP协议簇,默认状态下,分别通过TCP端口25、110和143建立连接。
SMTP即简单邮件传输协议,SMTP邮件服务器是遵循SMTP协议的发送邮件的服务器。如QQ:smtp.qq.com、163:smtp.163.com
POP即邮局协议,可以查询邮件,查询是否有新邮件,可以删除邮件。POP3是POP协议的第三个版本。如QQ:pop.qq.com、163:pop.163.com。
IMAP即互联网信息访问协议,此协议优于POP协议,拥有POP协议的功能,克服了POP协议的缺点。这里不做过多介绍。
MIME多用途互联网邮件扩展类型,这个不是协议,也在这里介绍,因为邮件消息需要遵循MIME扩展类型。具体的对照关系可以参看http://tool.oschina.net/commons

邮箱帐号的设置

在第三方客户端登录,需要设置帐号授权,获取授权码,此授权码将作为登录鉴权的密码使用。具体设置以QQ邮箱为例:

Setting.png
Javamail简介

JavaMail API提供了一种与平台无关和协议独立的框架来构建邮件和消息应用程序。下载地址:http://java.sun.com/products/javamail/
解压后将javax.mail.jar导入项目。
javamail主要的模块:

static Session getDefaultInstance(Properties props);
static Session getDefaultInstance(Properties props, Authenticator authenticator);
static Session getInstance(Properties props);
static Session getInstance(Properties props, Authenticator authenticator);

getDefaultInstance获取缺省初始对象,getInstance获取的都是新对象。
Properties对象复用java.util.Properties,SMTP协议属性参数设置如下:

Properties props = new Properties();
props.put("mail.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.qq.com");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");        props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.fallback", "false");

POP3协议属性参数设置如下:

Properties props = new Properties();
props.put("mail.debug", "true");
props.put("mail.pop3.host", "pop3.qq.com");
props.put("mail.pop3.port", "995");
props.put("mail.pop3.starttls.enable", "true");

Authenticator对象控制连接过程中的权限认证,设置代码如下:

Authenticator authenticator = new javax.mail.Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication("user:XXXX", "password:XXXX");
                    }

user是邮箱登录帐号,password是第三方客户端登录授权码

Message message = new MimeMessage(session);
message.setSubject("subject");
message.setContent("test", "text/plain;charset=UTF-8");
Multipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setText("test");
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);

这里涉及到MIME类型参考:http://tool.oschina.net/commons

Message.RecipientType.TO;
Message.RecipientType.Cc;
Message.RecipientType.Bcc;

设置发件人:

message.setFrom(new InternetAddress("xxx@qq.com"));

设置收件人:

message.setRecipients(Message.RecipientType.TO,InternetAddress.parse("xxx@qq.com;xxxx@qq.com"));
message.addRecipients(Message.RecipientType.Cc,InternetAddress.parse("xxx@qq.com;xxxx@qq.com"));
message.addRecipients(Message.RecipientType.Bcc,InternetAddress.parse("xxx@qq.com;xxx@qq.com"));

设置附件:

messageBodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(new DataHandler(new DataSource("xxxx")));
messageBodyPart.setFileName("filename");
multipart.addBodyPart(messageBodyPart);

附件对象构造依赖DataHandler对象,DataHandler对象构造依赖DataSource对象。DataSource就是通过读取文件二进制流生成。javax.mail.util.ByteArrayDataSource可以直接通过二进制流生成DataSource对象。

final ByteArrayDataSource dataSource = new ByteArrayDataSource(data, (type == null || "".equals(type)) ? "application/octet-stream" : type);
Transport transport = session.getTransport("smtps");
transport.connect("smtp.qq.com", 465, "xxx@qq.com", "password:xxxxx");
transport.sendMessage(message, message.getAllRecipients());
transport.close();
Folder emailFolder = store.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
//从folder中获取这些邮件信息并打印出来
Message[] messages  = emailFolder.getMessages();

Folder 对象表示邮局的一个文件目录,一个Message对象就是一封邮件,拆解的过程与组装过程相反。
当获取整个Store对象以后,我们可以做更多的操作,如删除邮件,移动邮件等。但删除邮件与邮件帐号的设置相关,需要授权给第三方客户端操作权限。具体设置,参看各邮件服务商的帐号设置选项。

注意

使用javamail在连接邮件服务器时connect报错:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

问题原因是jdk里面的jce包,安全性机制导致的访问https会报错,官网上有替代的jar包,下载替换:
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

总结

到此,邮件收发基本功能完成。后续需要思考:

借此项目作为学习java的契机,如有不当之处,请指正。
上一篇 下一篇

猜你喜欢

热点阅读