本文主要解决以下问题:
1、如何用java实现邮件发送功能?
2、如何发送给多个人、抄送给多个人?
3、如何发送携带附件的邮件?
开始说正文。
首先,发送邮件肯定要有个发件人,所有要有发件人的用户名和密码;然后得有服务器给中转吧,不同的邮箱对应的服务器也不一样,所以有邮件服务器的概念;再然后就是邮件本身,要有主题、收件人、抄送、正文、附件等等。
发件人的邮箱好说,随随便便就能申请到,可是邮件服务器呢?这里列出一些常用的邮件服务器(感谢数据的整理者):
- sina.com:
- POP3服务器地址:pop3.sina.com.cn(端口:110)
- SMTP服务器地址:smtp.sina.com.cn(端口:25)
- sinaVIP:
- POP3服务器:pop3.vip.sina.com (端口:110)
- SMTP服务器:smtp.vip.sina.com (端口:25)
- sohu.com:
- POP3服务器地址:pop3.sohu.com(端口:110)
- SMTP服务器地址:smtp.sohu.com(端口:25)
- 126邮箱:
- POP3服务器地址:pop.126.com(端口:110)
- SMTP服务器地址:smtp.126.com(端口:25)
- 139邮箱:
- POP3服务器地址:POP.139.com(端口:110)
- SMTP服务器地址:SMTP.139.com(端口:25)
- 163.com:
- POP3服务器地址:pop.163.com(端口:110)
- SMTP服务器地址:smtp.163.com(端口:25)
- QQ邮箱
- POP3服务器地址:pop.qq.com(端口:110)
- SMTP服务器地址:smtp.qq.com (端口:25)
- QQ企业邮箱
- POP3服务器地址:pop.exmail.qq.com (SSL启用 端口:995)
- SMTP服务器地址:smtp.exmail.qq.com(SSL启用 端口:587/465)
- yahoo.com:
- POP3服务器地址:pop.mail.yahoo.com
- SMTP服务器地址:smtp.mail.yahoo.com
- yahoo.com.cn:
- POP3服务器地址:pop.mail.yahoo.com.cn(端口:995)
- SMTP服务器地址:smtp.mail.yahoo.com.cn(端口:587
- HotMail
- POP3服务器地址:pop3.live.com (端口:995)
- SMTP服务器地址:smtp.live.com (端口:587)
- gmail(google.com)
- POP3服务器地址:pop.gmail.com(SSL启用 端口:995)
- SMTP服务器地址:smtp.gmail.com(SSL启用 端口:587)
- 263.net:
- POP3服务器地址:pop3.263.net(端口:110)
- SMTP服务器地址:smtp.263.net(端口:25)
- 263.net.cn:
- POP3服务器地址:pop.263.net.cn(端口:110)
- SMTP服务器地址:smtp.263.net.cn(端口:25)
- x263.net:
- POP3服务器地址:pop.x263.net(端口:110)
- SMTP服务器地址:smtp.x263.net(端口:25)
- 21cn.com:
- POP3服务器地址:pop.21cn.com(端口:110)
- SMTP服务器地址:smtp.21cn.com(端口:25)
- Foxmail:
- POP3服务器地址:POP.foxmail.com(端口:110)
- SMTP服务器地址:SMTP.foxmail.com(端口:25)
- china.com:
- POP3服务器地址:pop.china.com(端口:110)
- SMTP服务器地址:smtp.china.com(端口:25)
- tom.com:
- POP3服务器地址:pop.tom.com(端口:110)
- SMTP服务器地址:smtp.tom.com(端口:25)
- etang.com:
- POP3服务器地址:pop.etang.com
- SMTP服务器地址:smtp.etang.com
好嘞,有了这个之后就开始今天的正事,讲讲怎么用java发送邮件,首先上原理( 原文在此 )。
JAVA MAIL是利用现有的邮件账户发送邮件的工具,比如说,我在网易注册一个邮箱账户,通过JAVA Mail的操控,我可以不亲自登录网易邮箱,让程序自动的使用网易邮箱发送邮件。这一机制被广泛的用在注册激活和垃圾邮件的发送等方面。
JavaMail可以到http://www.oracle.com/technetwork/java/javamail/index-138643.html进行下载,并将mail.jar添加到classpath即可。如果你使用的是JAVA EE SDK,则可以在C:\glassfishv3\glassfish\modules\mail.jar找到所需的jar包,同样需要添加的classpath。
JAVA邮件发送的大致过程是这样的的:
1、构建一个继承自javax.mail.Authenticator的具体类,并重写里面的getPasswordAuthentication()方法。此类是用作登录校验的,以确保你对该邮箱有发送邮件的权利。
2、构建一个properties文件,该文件中存放SMTP服务器地址等参数。
3、通过构建的properties文件和javax.mail.Authenticator具体类来创建一个javax.mail.Session。Session的创建,就相当于登录邮箱一样。剩下的自然就是新建邮件。
4、构建邮件内容,一般是javax.mail.internet.MimeMessage对象,并指定发送人,收信人,主题,内容等等。
5、使用javax.mail.Transport工具类发送邮件。
接下来上干货
- import java.util.Iterator;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Properties;
- import javax.activation.DataHandler;
- import javax.activation.FileDataSource;
- import javax.mail.BodyPart;
- import javax.mail.Message;
- import javax.mail.Multipart;
- import javax.mail.Session;
- import javax.mail.Transport;
- import javax.mail.internet.InternetAddress;
- import javax.mail.internet.MimeBodyPart;
- import javax.mail.internet.MimeMessage;
- import javax.mail.internet.MimeMultipart;
- import javax.mail.internet.MimeUtility;
- public class Email {
- private static String defaultSenderName = "";// 默认的发件人用户名,defaultEntity用得到
- private static String defaultSenderPass = "";// 默认的发件人密码,defaultEntity用得到
- private static String defaultSmtpHost = "";// 默认的邮件服务器地址,defaultEntity用得到
- private String smtpHost; // 邮件服务器地址
- private String sendUserName; // 发件人的用户名
- private String sendUserPass; // 发件人密码
- private MimeMessage mimeMsg; // 邮件对象
- private Session session;
- private Properties props;
- private Multipart mp;// 附件添加的组件
- private List<FileDataSource> files = new LinkedList<FileDataSource>();// 存放附件文件
- private void init() {
- if (props == null) {
- props = System.getProperties();
- }
- props.put("mail.smtp.host", smtpHost);
- props.put("mail.smtp.auth", "true"); // 需要身份验证
- session = Session.getDefaultInstance(props, null);
- // 置true可以在控制台(console)上看到发送邮件的过程
- session.setDebug(true);
- // 用session对象来创建并初始化邮件对象
- mimeMsg = new MimeMessage(session);
- // 生成附件组件的实例
- mp = new MimeMultipart();
- }
- private Email(String smtpHost, String sendUserName, String sendUserPass, String to, String cc, String mailSubject, String mailBody,
- List<String> attachments) {
- this.smtpHost = smtpHost;
- this.sendUserName = sendUserName;
- this.sendUserPass = sendUserPass;
- init();
- setFrom(sendUserName);
- setTo(to);
- setCC(cc);
- setBody(mailBody);
- setSubject(mailSubject);
- if (attachments != null) {
- for (String attachment : attachments) {
- addFileAffix(attachment);
- }
- }
- }
- /**
- * 邮件实体
- *
- * @param smtpHost
- * 邮件服务器地址
- * @param sendUserName
- * 发件邮件地址
- * @param sendUserPass
- * 发件邮箱密码
- * @param to
- * 收件人,多个邮箱地址以半角逗号分隔
- * @param cc
- * 抄送,多个邮箱地址以半角逗号分隔
- * @param mailSubject
- * 邮件主题
- * @param mailBody
- * 邮件正文
- * @param attachmentPath
- * 附件路径
- * @return
- */
- public static Email entity(String smtpHost, String sendUserName, String sendUserPass, String to, String cc, String mailSubject, String mailBody,
- List<String> attachments) {
- return new Email(smtpHost, sendUserName, sendUserPass, to, cc, mailSubject, mailBody, attachments);
- }
- /**
- * 默认邮件实体,用了默认的发送帐号和邮件服务器
- *
- * @param to
- * 收件人,多个邮箱地址以半角逗号分隔
- * @param cc
- * 抄送,多个邮箱地址以半角逗号分隔
- * @param subject
- * 邮件主题
- * @param body
- * 邮件正文
- * @param attachment
- * 附件全路径
- * @return
- */
- public static Email defaultEntity(String to, String cc, String subject, String body, List<String> attachments) {
- return new Email(defaultSmtpHost, defaultSenderName, defaultSenderPass, to, cc, subject, body, attachments);
- }
- /**
- * 设置邮件主题
- *
- * @param mailSubject
- * @return
- */
- private boolean setSubject(String mailSubject) {
- try {
- mimeMsg.setSubject(mailSubject);
- } catch (Exception e) {
- return false;
- }
- return true;
- }
- /**
- * 设置邮件内容,并设置其为文本格式或HTML文件格式,编码方式为UTF-8
- *
- * @param mailBody
- * @return
- */
- private boolean setBody(String mailBody) {
- try {
- BodyPart bp = new MimeBodyPart();
- bp.setContent("<meta http-equiv=Content-Type content=text/html; charset=UTF-8>" + mailBody, "text/html;charset=UTF-8");
- // 在组件上添加邮件文本
- mp.addBodyPart(bp);
- } catch (Exception e) {
- System.err.println("设置邮件正文时发生错误!" + e);
- return false;
- }
- return true;
- }
- /**
- * 添加一个附件
- *
- * @param filename
- * 邮件附件的地址,只能是本机地址而不能是网络地址,否则抛出异常
- * @return
- */
- public boolean addFileAffix(String filename) {
- try {
- if (filename != null && filename.length() > 0) {
- BodyPart bp = new MimeBodyPart();
- FileDataSource fileds = new FileDataSource(filename);
- bp.setDataHandler(new DataHandler(fileds));
- bp.setFileName(MimeUtility.encodeText(fileds.getName(), "utf-8", null)); // 解决附件名称乱码
- mp.addBodyPart(bp);// 添加附件
- files.add(fileds);
- }
- } catch (Exception e) {
- System.err.println("增加邮件附件:" + filename + "发生错误!" + e);
- return false;
- }
- return true;
- }
- /**
- * 删除所有附件
- *
- * @return
- */
- public boolean delFileAffix() {
- try {
- FileDataSource fileds = null;
- for (Iterator<FileDataSource> it = files.iterator(); it.hasNext();) {
- fileds = it.next();
- if (fileds != null && fileds.getFile() != null) {
- fileds.getFile().delete();
- }
- }
- } catch (Exception e) {
- return false;
- }
- return true;
- }
- /**
- * 设置发件人地址
- *
- * @param from
- * 发件人地址
- * @return
- */
- private boolean setFrom(String from) {
- try {
- mimeMsg.setFrom(new InternetAddress(from));
- } catch (Exception e) {
- return false;
- }
- return true;
- }
- /**
- * 设置收件人地址
- *
- * @param to收件人的地址
- * @return
- */
- private boolean setTo(String to) {
- if (to == null)
- return false;
- try {
- mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
- } catch (Exception e) {
- return false;
- }
- return true;
- }
- /**
- * 设置抄送
- *
- * @param cc
- * @return
- */
- private boolean setCC(String cc) {
- if (cc == null) {
- return false;
- }
- try {
- mimeMsg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc));
- } catch (Exception e) {
- return false;
- }
- return true;
- }
- /**
- * 发送邮件
- *
- * @return
- */
- public boolean send() throws Exception {
- mimeMsg.setContent(mp);
- mimeMsg.saveChanges();
- System.out.println("正在发送邮件....");
- Transport transport = session.getTransport("smtp");
- // 连接邮件服务器并进行身份验证
- transport.connect(smtpHost, sendUserName, sendUserPass);
- // 发送邮件
- transport.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.TO));
- System.out.println("发送邮件成功!");
- transport.close();
- return true;
- }
- }
我自己写的一个封装的Email类,提供了两个静态的方法获取实体,send方法用来发送邮件,附上测试代码
- import java.util.Arrays;
- import java.util.List;
- import org.junit.Test;
- import smok.springmvc.model.Email;
- public class EmailTest {
- @Test
- public void sendEmail() throws Exception {
- String userName = "11111111@qq.com"; // 发件人邮箱
- String password = "********"; // 发件人密码
- String smtpHost = "smtp.qq.com"; // 邮件服务器
- String to = "22222222@qq.com"; // 收件人,多个收件人以半角逗号分隔
- String cc = "33333333@qq.com"; // 抄送,多个抄送以半角逗号分隔
- String subject = "这是邮件的主题"; // 主题
- String body = "这是邮件的正文"; // 正文,可以用html格式的哟
- List<String> attachments = Arrays.asList("D:\\tmp\\1.png", "D:\\tmp\\2.png"); // 附件的路径,多个附件也不怕
- Email email = Email.entity(smtpHost, userName, password, to, cc, subject, body, attachments);
- email.send(); // 发送!
- }
- }
直接粘代码可是会报错的,这里边依赖了几个包,我把pom也放上来
- <span style="white-space:pre"> </span><dependency>
- <groupId>javax.mail</groupId>
- <artifactId>javax.mail-api</artifactId>
- <version>1.5.2</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.sun.mail</groupId>
- <artifactId>smtp</artifactId>
- <version>1.5.2</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.sun.mail</groupId>
- <artifactId>mailapi</artifactId>
- <version>1.5.2</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.9</version>
- <scope>test</scope>
- </dependency>
到这里应该已经解决了开头提到的三个问题了
1、发送邮件,ok
2、发送给多个人,只有以半角逗号分隔收件人就可以了,抄送也是一样的方式
3、发送附件,只要有文件的全路径,发送多个文件也没问题呀~
总算是把发邮件这个事情搞定了,以后遇到cover不到的情况再来补充。