Java邮件发送收取和监听

邮件协议

本文涉及到的协议主要包含:SMTP(Simple Mail Transfer Protocol,简单邮件传输协议),POP3(Post Office Protocol,邮局协议),IMAP(Internet Message Access Protocol,Internet邮件访问协议)。
通常情况下,smtp用来发送邮件。pop3和imap用来接收邮件,这样就有了pop3和imap有什么差别的疑问,大体上的差别在于,pop3虽然可以接收服务器上的邮件但是它对邮件的操作,比如,移动标记已读等等,都不会被反馈到客户端。imap提供客户端与服务端之间的双向通信,客户端对邮件的操作会反馈给服务端,客户端的操作,服务端也会同步做相应的操作,imap协议支持idle。
总体上来说,imap有很多优点,这些都是pop3所不能比的,但是国内的邮件服务商对imap的协议支持参差不齐,也限制了imap在国内的使用普及程度。

配置

配置项说明
mail.xxx.host邮件服务器主机
mail.xxx.port邮件服务器端口
mail.xxx.auth是否身份验证
mail.xxx.ssl.enable是否启用SSL

默认端口

配置项SMTPPOP3IMAP
普通方式25110143
SSL方式465995993

 

发送邮件

ieayoio_from@163.com给ieayoio_to@163.com,这里使用SSL协议,SSL协议的默认端口为465:

import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
/**
 * Created by ieayoio on 16-9-19.
 */
public class SendMail {
    public static void main(String[] args) {
        boolean isSSL = true;
        String host = "smtp.163.com";
//        int port = 25;
        int port = 465;
        String from = "ieayoio_from@163.com";
        String to = "ieayoio_to@163.com";
        boolean isAuth = true;
        final String username = "ieayoio_from@163.com";
        final String password = "ieayoio.tk";
        Properties props = new Properties();
        props.put("mail.smtp.ssl.enable", isSSL);
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", isAuth);
        Session session = Session.getDefaultInstance(props, new Authenticator() {
            
@Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
        });
        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = df.format(new Date());
            message.setSubject("ieayoio的邮件测试" + format);
            message.setText("博客ieayoio.tk");
            Transport.send(message);
        } catch (AddressException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        System.out.println("发送完毕!");
    }
}

接收邮件

使用SSL,接收username@163.com的邮件,假设他的密码是bob123456。

import javax.mail.*;
import java.util.Date;
import java.util.Properties;
/**
 * Created by ieayoio on 16-9-19.
 */
public class FetchMail {
    public static void main(String[] args) {
        String protocol = "pop3";
        boolean isSSL = true;
        String host = "pop.163.com";
        int port = 995;
        String username = "username@163.com";
        String password = "bob123456";
        Properties props = new Properties();
        props.put("mail.pop3.ssl.enable", isSSL);
        props.put("mail.pop3.host", host);
        props.put("mail.pop3.port", port);
        Session session = Session.getDefaultInstance(props);
        Store store = null;
        Folder folder = null;
        try {
            store = session.getStore(protocol);
            store.connect(username, password);
            folder = store.getFolder("INBOX");
            folder.open(Folder.READ_ONLY);
            int size = folder.getMessageCount();
            System.out.println("邮件个数:" + size);
            System.out.println("最新一封邮件为:");
            Message message = folder.getMessage(size);
            String from = message.getFrom()[0].toString();
            String subject = message.getSubject();
            Date date = message.getSentDate();
            System.out.println("From: " + from);
            System.out.println("Subject: " + subject);
            System.out.println("Date: " + date);
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        } finally {
            try {
                if (folder != null) {
                    folder.close(false);
                }
                if (store != null) {
                    store.close();
                }
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
        System.out.println("接收完毕!");
    }
}

邮件的监听收取

简单的收取邮件是一次性的,但是实际使用中,我们并不知道什么时候才会有新的邮件可收取,这时可以使用邮件监听,来实时获取邮件,这里我们使用imap协议,因为imap是支持idle的,如果所要收取的邮件服务器不支持idle,我们将将采用轮询的方式收取,这里要注意的是调用folder.getMessageCount()时可能会触发addMessageCountListener的调用。

import com.sun.mail.imap.IMAPFolder;
import javax.mail.*;
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;
import java.util.Properties;
/**
 * Created by ieayoio on 16-9-19.
 */
public class Monitor {
    public static void main(String args[]) {
        System.out.println("\nTesting monitor\n");
        String host = "imap.163.com";
        int port = 993;
        String user = "username@163.com";
        String password = "bob132456";
        String mbox = "INBOX";
        String freqs = "5000";
        boolean isOpenidle = true;
        try {
            Properties props = System.getProperties();
            // 得到session对象
            Session session = Session.getInstance(props, null);
            // session.setDebug(true);
            // 获取store对象
            Store store = session.getStore("imap");
            // Connect
            store.connect(host, port, user, password);
            // Open a Folder
            Folder folder = store.getFolder(mbox);
            if (folder == null || !folder.exists()) {
                System.out.println("Invalid folder");
                System.exit(1);
            }
            folder.open(Folder.READ_WRITE);
            // Add messageCountListener to listen for new messages
            folder.addMessageCountListener(new MessageCountAdapter() {
                public void messagesAdded(MessageCountEvent ev) {
                    Message[] msgs = ev.getMessages();
                    System.out.println("Got " + msgs.length + " new messages");
                    // Just dump out the new messages
                    for (int i = 0; i < msgs.length; i++) {
                        try {
                            System.out.println("-----");
                            System.out.println("Message " +
                                    msgs[i].getMessageNumber() + ":");
                            System.out.println(msgs[i].getSubject());
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            });
            // 检查是否支持imap idle,尝试使用idle
            int freq = Integer.parseInt(freqs);
            boolean supportsIdle = false;
            try {
                if (isOpenidle && folder instanceof IMAPFolder) {
                    IMAPFolder f = (IMAPFolder) folder;
                    f.idle();
                    supportsIdle = true;
                }
            } catch (FolderClosedException fex) {
                throw fex;
            } catch (MessagingException mex) {
                supportsIdle = false;
            }
            for (; ; ) {
                if (supportsIdle && folder instanceof IMAPFolder) {
                    IMAPFolder f = (IMAPFolder) folder;
                    f.idle();
                } else {
                    System.out.println("idle不支持进入轮询");
                    Thread.sleep(freq); // sleep for freq milliseconds
                    // 注意。getMessageCount时会触发监听器
                    folder.getMessageCount();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

使用开源组件简单的邮件开发

大多数的文章讲解的是使用Apache Commons Email来进行一些邮件的简化开发,这里就不在对其进行介绍,有兴趣可以百度google,这里介绍另一种开源组件JoddMail,JoddMail可以方便的进行收发邮件,简化邮件的开发是一个不错的选择,以下是一段没有经过编译的代码简单展示一下使用SSL的方式发送邮件,有兴趣可以去官网查看使用说明

/**
 * Created by ieayoio on 16-9-26.
 */
public class JoddSend {
    public static void main(String[] args) {
        SmtpServer smtpServer = SmtpSslServer
                .create("smtp.gmail.com")
                .authenticateWith("ieayoio_from@jodd.org", "password");
        Email email = Email.create()
                .from("ieayoio_from@jodd.org")
                .to("ieayoio_to@jodd.org")
                .subject("Hello!")
                .addText("ieayoio.tk");
        SendMailSession session = smtpServer.createSession();
        session.open();
        session.sendMail(email);
        session.close();
    }
}

参考链接:
https://my.oschina.net/huangyong/blog/178641
https://github.com/liutian/java-mail
http://jodd.org/doc/email.html

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值