JavaMail概述

JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(Java Development Kit),这就意味着你在使用前必须另外下载JavaMail文件。
另外很好的实现了JavaMail API的框架有James、Spring Mail。

核心API

A.JavaMail核心类结构
JavaMail.jar文件的一些核心类:Session、Message、Address、Authenticator、Transport、Store、Folder。

B.Session(邮件会话)
进行收发邮件的工作都是基于这个会话的。
Session对象利用了java.util.Properties对象获得了邮件服务器、用户名、密码信息和整个应用程序都要使用到的共享信息。

Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);

或者

Properties props = new Properties();
Session session = Session.getInstance(props, null);

从上面的两个例子中不难发现,第二个参数都是null,这是因为在上面的例子中并没有使用到邮件授权(参考E)

C.Message
建立了Session对象后,便可以被发送的构造信息体Message抽象类
使用javax.mail.internet.MimeMessage这个子类,该类是使用MIME类型、MIME信息头的邮箱信息。
信息头只能使用US-ASCII字符

Message message = new MimeMessage(session);
message.setContent("Hello", "text/plain");//非文本信息内容
message.setText("Hello");//纯文本信息内容
message.setSubject("First");//设置邮件主题
message.setSentDate(Date);//设置邮件发送日期

D.Address
建立了Session和Message对象后,使用邮件地址Address抽象类
使用javax.mail.internet.InternetAddress这个子类。通过传入邮件地址的字符串

Address address = new InternetAddress("kuangye89757@163.com"); //邮件地址
Address address = new InternetAddress("president@whitehouse.gov", "George Bush"); //带名字的邮件地址
message.setFrom(address);//设置发信人
message.setReplyTo(address);//同上
message.addFrom(Address[] address);//添加多个发信人

message.addRecipient(type, address)//设置收信人
Message.RecipientType.TO//收信人
Message.RecipientType.CC//抄送人
Message.RecipientType.BCC//暗送人

E.Authenticator授权者类
使用Authenticator抽象类必须实现getPasswordAuthentication()方法(用于存储认证时要用到的用户名、密码)。
并且要在Session中进行注册,使Session能够了解在认证时该使用哪个类。

Properties props = new Properties();
Authenticator auth = new MyAuthenticator();
Session session = Session.getDefaultInstance(props, auth);
/**
 * 自定义邮件授权类
 * @return
 * @throws IOException
 */
public class MyAuthenticator  extends Authenticator {
      public PasswordAuthentication getPasswordAuthentication(String param) {
        String username;
        String password;
        StringTokenizer st = new StringTokenizer(param, ",");
        username = st.nextToken();
        password = st.nextToken();
        return new PasswordAuthentication(username, password);
    }
}

F.Transport
发送信息时使用Transport抽象类(实现了SMTP)
Transport.send(MimeMessage message);

或者一般用法
当然,方法是多样的。我们也可由Session获得相应协议对应的Transport实例。并通过传递用户名、密码、邮件服务器主机名等参数建立与邮件服务器的连接,并使用sendMessage()方法将信息发送,最后关闭连接:

session.setDebug(true);//监控邮件发送过程
message.saveChanges(); //保存文件
Transport transport = session.getTransport("smtp");//获取实现了SMTP协议的Transport类
transport.connect(host, username, password);//连接服务器
transport.sendMessage(message, message.getAllRecipients());//发送邮件给所有收件人
transport.close();//关闭连接

G.Store(存储邮件的服务器)和Folder(目录对象)

Store store = session.getStore("pop3");
store.connect(host, username, password);

Folder folder = store.getFolder("INBOX");//POP3协议只有一个名为INBOX的Folder有效
folder.open(Folder.READ_ONLY);//只读方式打开
Message message[] = folder.getMessages();//获得邮件
System.out.println(((MimeMessage)message).getContent());//邮件内容(不包含邮件头)
System.out.println(((MimeMessage)message).writeTo());//邮件内容(含邮件头)
folder.close(true);//若删除邮件则及时更新Folder,关闭
store.close();//关闭

开发准备

  1. 申请邮箱,开通POP3/SMTP服务
  2. pom.xml引入依赖
<!-- JavaMail -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4</version>
</dependency>
<!-- 引入Spring对JavaMail集成 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>

JavaMail开发

/**
         * 邮件发送工具类
         */
        public class MailUtils {


            /**
             * 发送邮件
             * @param host  邮件传送协议服务器
             * @param username  发件人用户名
             * @param password  发件人用户密码
             * @param addr    收件人地址
             * @param subject 邮件主题
             * @param text  邮件内容
             * @throws MessagingException
             */
            public static void sendMail(String host,String username,String password,String addr,String subject,String text) throws MessagingException{
                Properties properties = new Properties();
                properties.put("mail.smtp.host", host);
                properties.put("mail.smtp.auth", "true");
                //创建邮件会话
                Session session = Session.getInstance(properties);
                //构建信息体
                Message message = new MimeMessage(session);
                //发送地址
                InternetAddress address = new InternetAddress(username);
                message.setFrom(address);
                //收件地址
                InternetAddress toAddress = new InternetAddress(addr);
                message.setRecipient(MimeMessage.RecipientType.TO, toAddress);
                //主题
                message.setSubject(subject);
                //正文
                message.setText(text);
                //保存文件
                message.saveChanges();
                //获取实现了SMTP协议的Transport类
                Transport transport = session.getTransport("smtp");
                //连接服务器
                transport.connect(host, username, password);
                //发送邮件给所有收件人
                transport.sendMessage(message, message.getAllRecipients());
                //关闭连接
                transport.close();
            }
        }

Spring Mail开发

Spring邮件抽象层的主要包为org.springframework.mail。它包括了发送邮件的主要接口MailSender,和其实现类SimpleMailMessage,它封装了简单邮件的属性如:from,to,cc,subject,text。包里还包含一颗以MailException为根的checkedException继承树,它们提供了对底层邮件系统异常的高级别抽象。要获得关于邮件异常层次的更丰富的信息。
为了使用JavaMail中的一些特色,比如MIME类型的信件,spring 提供了MailSender的一个子接口,即org.springframework.mail.javamail.JavaMailSender。Spring还提供了一个回调接口 org.springframework.mail.javamail.MimeMessagePreparator,用于准备JavaMail的MIME信件。

  • SimpleMailMessage 发送简单邮件
  • JavaMailSender、JavaMailSenderImpl 发送邮件的类
  • MimeMailMessage 发送带附件的邮件
  1. 在src目录下建立mail.properties文件
    文件内容:
mail.host=邮件协议
mail.username=邮箱名
mail.password=邮箱密码
mail.auth=授权(true)
mail.from=发件人邮箱
  1. spring配置
<?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:context="http://www.springframework.org/schema/context"
            xmlns:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xmlns:jpa="http://www.springframework.org/schema/data/jpa"
            xmlns:p="http://www.springframework.org/schema/p"
            xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

            <!-- 加载Properties 文件 -->
            <bean id="configurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                <property name="locations">
                    <list>
                        <value>classpath:mail.properties</value>
                    </list>
                </property>
            </bean>
            <bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
                <property name="from">
                    <value>${mail.from}</value>
                </property>
                <!-- 查看源码,还可以注入标题,内容等 -->
            </bean>
            <!-- 声明JavaMailSenderImpl对象 -->
            <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
                <property name="defaultEncoding" value="UTF-8" />
                <!-- 配置mail属性,与mail.properties对应 -->
                <property name="host" value="${mail.host}" />
                <property name="username" value="${mail.username}" />
                <property name="password" value="${mail.password}" />
                <property name="javaMailProperties">
                    <props>
                        <!-- 设置认证开关 -->
                        <prop key="mail.smtp.auth">true</prop>
                        <!--启动调试开关 -->
                        <prop key="mail.debug">true</prop>
                        <!-- 设置发送延时 -->
                        <prop key="mail.smtp.timeout">0</prop>
                    </props>
                </property>
            </bean>
        </beans>
  1. 发送简单邮件
/**
         * 测试发送Html格式的邮件
         */
        public class SingleMailSend {

            //获取spring容器
            static ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-email.xml");
            //从spring容器中获取发送简单邮件的发送策略
            //MailSender,This interface defines a strategy for sending simple mails
            static MailSender sender = (MailSender) context.getBean("mailSender");
            //从spring容器中获取简单邮件模板包含from, to, cc, subject, and text fields
            //SimpleMailMessage,Models a simple mail message, including data such as the from, to, cc, subject, and text fields
            static SimpleMailMessage mailMessage = (SimpleMailMessage) context.getBean("mailMessage");

            public static void main(String[] args) throws MessagingException{
                mailMessage.setSubject("测试");
                mailMessage.setText("这个一个通过spring框架来发送的邮件");
                mailMessage.setTo("xxx@qq.com");
                //发送邮件
                sender.send(mailMessage);
            }
        }
  1. 发送带有图片的邮件,嵌入Html中
/**
         * 发送Html中嵌入图片的邮件
         */
        public class SpringAttachedImageMail {

            public static void main(String[] args) throws MessagingException {
                //获取spring容器
                ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-email.xml");
                //获取MimeMessage发送者,也支持发送简单的邮件
                JavaMailSenderImpl sender = (JavaMailSenderImpl) context.getBean("mailSender");
                //获取message,支持MIME格式可支持非文本格式附件(二进制、声音、图像等),
                MimeMessage mailMessage = sender.createMimeMessage();
                //为message提供支持
                MimeMessageHelper messageHelper = new MimeMessageHelper(mailMessage,true);
                messageHelper.setFrom("xxx@163.com");
                messageHelper.setTo("xxx@qq.com");
                messageHelper.setSubject("测试邮件中嵌入图片");
                //true表示启动HTML格式的邮件
                messageHelper.setText("<html><head></head><body><h1>测试,Spring框架发送嵌入图片的Html邮件!</h1>"
                        + "<a href=http://www.baidu.com>百度</a><img src=cid:image/></body></html>",true);
                //设置图片
                FileSystemResource img = new FileSystemResource(new File("src/test/resources/test.png"));
                //邮件中嵌入图片,与cid对应
                messageHelper.addInline("image", img); 
                //发送邮件
                sender.send(mailMessage);
            }
        }
  1. 发送带附件的邮件
/**
         * 发送带附件的邮件
         */
        public class SpringAttachedTextMail {

            public static void main(String[] args) throws MessagingException {
                //获取spring容器
                ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-email.xml");
                //与spring整合时注入
                JavaMailSenderImpl sender = (JavaMailSenderImpl) context.getBean("mailSender");
                //与spring整合时注入
                MimeMessage mimeMessage = sender.createMimeMessage();
                MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
                messageHelper.setFrom("xxx@163.com");
                messageHelper.setTo("xxx@qq.com");
                messageHelper.setSubject("邮件中带附件!");
                messageHelper.setText("<html><head></head><body><h1>测试,Spring框架发送附件的Html邮件!</h1>"
                        + "<a href=http://www.baidu.com>百度</a><img src=cid:image/></body></html>",true);
                FileSystemResource img = new FileSystemResource(new File("src/test/resources/test.png"));
                //添加附件
                messageHelper.addAttachment("测试图片附件.png", img);
                sender.send(mimeMessage);
            }
        }