邮件协议
1 收发邮件
发邮件是从客户端把邮件发送到邮件服务器,收邮件是把邮件服务器的邮件下载到客户端。我们在163、126、QQ、sohu、sina等网站注册的Email账户,其实就是在邮件服务器中注册的。这些网站都有自己的邮件服务器。

2 邮件协议概述
与HTTP协议相同,收发邮件也是需要有传输协议的。
SMTP:(Simple Mail Transfer Protocol,简单邮件传输协议)发邮件协议;
POP3:(Post Office Protocol Version 3,邮局协议第3版)收邮件协议;
IMAP:(Internet Message Access Protocol,因特网消息访问协议)收发邮件协议。
3 理解邮件收发过程
其实你可以把邮件服务器理解为邮局!如果你需要给朋友寄一封信,那么你需要把信放到邮筒中,这样你的信会“自动”到达邮局,邮局会把信邮到另一个省市的邮局中。然后这封信会被送到收信人的邮箱中。最终收信人需要自己经常查看邮箱是否有新的信件。
其实每个邮件服务器都由SMTP服务器和POP3服务器构成,其中SMTP服务器负责发邮件的请求,而POP3负责收邮件的请求。当然,有时我们也会使用163的账号,向126的账号发送邮件。这时邮件是发送到126的邮件服务器,而对于163的邮件服务器是不会存储这封邮件的。


4 邮件服务器名称
smtp服务器的端口号为25,服务器名称为smtp.xxx.xxx。
pop3服务器的端口号为110,服务器名称为pop3.xxx.xxx。
例如:
163:smtp.163.com和pop3.163.com;
126:smtp.126.com和pop3.126.com;
qq:smtp.qq.com和pop3.qq.com;
sohu:smtp.sohu.com和pop3.sohu.com;
JavaMail
1 JavaMail概述
Java Mail是由SUN公司提供的专门针对邮件的API,主要Jar包:mail.jar、activation.jar。
在使用MyEclipse创建web项目时,需要小心!如果只是在web项目中使用java mail是没有什么问题的,发布到Tomcat上运行一点问题都没有!但是如果是在web项目中写测试那就出问题了。在MyEclipse中,会自动给web项目导入javax.mail包中的类,但是不全(其实是只有接口,而没有接口的实现类),所以只靠MyEclipse中的类是不能运行java mail项目的,但是如果这时你再去自行导入mail.jar时,就会出现冲突。
处理方案:到下面路径中找到javaee.jar文件,把javax.mail删除!!!
D:\myeclipse\Common\plugins\com.genuitec.eclipse.j2eedt.core_10.0.0.me201110301321\data\libraryset\EE_5
2 JavaMail中主要类
java mail中主要类:javax.mail.Session、javax.mail.internet.MimeMessage、javax.mail.Transport。
Session:表示会话,即客户端与邮件服务器之间的会话!想获得会话需要给出账户和密码,当然还要给出服务器名称。在邮件服务中的Session对象,就相当于连接数据库时的Connection对象。
MimeMessage:表示邮件类,它是Message的子类。它包含邮件的主题(标题)、内容,收件人地址、发件人地址,还可以设置抄送和暗送,甚至还可以设置附件。
Transport:用来发送邮件。它是发送器!
3 JavaMail之Hello World
在使用telnet发邮件时,还需要自己来处理Base64编码的问题,但使用JavaMail就不必理会这些问题了,都由JavaMail来处理。
第一步:获得Session
Session session = Session.getInstance(Properties prop, Authenticator auth);
//其中prop需要指定两个键值,一个是指定服务器主机名,另一个是指定是否需要认证!我们当然需要认证!
Properties prop = new Properties();
prop.setProperty(“mail.host”, “smtp.163.com”);//设置服务器主机名
prop.setProperty(“mail.smtp.auth”, “true”);//设置需要认证
//其中Authenticator是一个接口表示认证器,即校验客户端的身份。我们需要自己来实现这个接口,实现这个接口需要使用账户和密码。
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication () {
new PasswordAuthentication(“xxx”, “yyy”);//用户名和密码,该密码为授权码
}
};
//通过上面的准备,现在可以获取得Session对象了:
Session session = Session.getInstance(prop, auth);
第二步:创建MimeMessage对象
//创建MimeMessage需要使用Session对象来创建: MimeMessage msg = new MimeMessage(session); //然后需要设置发信人地址、收信人地址、主题,以及邮件正文。 msg.setFrom(new InternetAddress(“xxx@163.com”));//设置发信人 msg.addRecipients(RecipientType.TO, “yyy1@qq.com,yyy2@sina.com”);//设置多个收信人 msg.addRecipients(RecipientType.CC, “zzz1@sohu.com,zzz2@126.com”);//设置多个抄送 msg.addRecipients(RecipientType.BCC, ”kkk@163.com”);//设置暗送 msg.setSubject(“测试邮件”);//设置主题(标题) msg.setContent(“hello world!”, “text/plain;charset=utf-8”);//设置正文
第三步:发送邮件
Transport.send(msg);//发送邮件
4 JavaMail发送带有附件的邮件(了解)
一封邮件可以包含正文、附件N个,所以正文与N个附件都是邮件的一个部份。
上面的hello world案例中,只是发送了带有正文的邮件!所以在调用setContent()方法时直接设置了正文,如果想发送带有附件邮件,那么需要设置邮件的内容为MimeMultiPart。
MimeMulitpart parts = new MimeMulitpart();//多部件对象,可以理解为是部件的集合 msg.setContent(parts);//设置邮件的内容为多部件内容。 //然后我们需要把正文、N个附件创建为“主体部件”对象(MimeBodyPart),添加到MimeMuiltPart中即可。 MimeBodyPart part1 = new MimeBodyPart();//创建一个部件 part1.setCotnent(“这是正文部分”, “text/html;charset=utf-8”);//给部件设置内容 parts.addBodyPart(part1);//把部件添加到部件集中。 //下面我们创建一个附件: MimeBodyPart part2 = new MimeBodyPart();//创建一个部件 part2.attachFile(“F:/Lebron.jpeg”);//设置附件 part2.setFileName(“hello.jpg”);//设置附件名称 parts.addBodyPart(part2);//把附件添加到部件集中 //注意,如果在设置文件名称时,文件名称中包含了中文的话,那么需要使用MimeUitlity类来给中文编码: //part2.setFileName(MimeUitlity.encodeText(“美女.jpg”));
应用实例1(普通方式发送):

1 import java.io.File;
2 import java.util.Properties;
3 import javax.mail.Authenticator;
4 import javax.mail.Message.RecipientType;
5 import javax.mail.PasswordAuthentication;
6 import javax.mail.Session;
7 import javax.mail.Transport;
8 import javax.mail.internet.InternetAddress;
9 import javax.mail.internet.MimeBodyPart;
10 import javax.mail.internet.MimeMessage;
11 import javax.mail.internet.MimeMultipart;
12 import javax.mail.internet.MimeUtility;
13 import org.junit.Test;
14 public class Demo1 {
15 //发送普通邮件
16 @Test
17 public void fun1() throws Exception {
18 //1. 得到session
19 Properties props = new Properties();
20 props.setProperty("mail.host", "smtp.163.com");
21 props.setProperty("mail.smtp.auth", "true");
22 Authenticator auth = new Authenticator() {
23 @Override
24 protected PasswordAuthentication getPasswordAuthentication() {
25 return new PasswordAuthentication("xxx", "yyy");//注意:该密码为授权码
26 }
27 };
28 Session session = Session.getInstance(props, auth);
29 //2. 创建MimeMessage
30 MimeMessage msg = new MimeMessage(session);
31 msg.setFrom(new InternetAddress("xxx@163.com"));//设置发件人
32 msg.setRecipients(RecipientType.TO, "zzz@qq.com");//设置收件人
33 msg.setSubject("测试邮件");
34 msg.setContent("hello world!", "text/html;charset=utf-8");
35 //3. 发
36 Transport.send(msg);
37 }
38 //带有附件的邮件
39 @Test
40 public void fun2() throws Exception {
41 //1. 得到session
42 Properties props = new Properties();
43 props.setProperty("mail.host", "smtp.163.com");
44 props.setProperty("mail.smtp.auth", "true");
45 Authenticator auth = new Authenticator() {
46 @Override
47 protected PasswordAuthentication getPasswordAuthentication() {
48 return new PasswordAuthentication("xxx", "yyy");
49 }
50 };
51 Session session = Session.getInstance(props, auth);
52 //2. 创建MimeMessage
53 MimeMessage msg = new MimeMessage(session);
54 msg.setFrom(new InternetAddress("xxx@163.com"));//设置发件人
55 msg.setRecipients(RecipientType.TO, "zzz@qq.com");//设置收件人
56 msg.setSubject("测试邮件有附件");
57 /*
58 * 当发送包含附件的邮件时,邮件体就为多部件形式!
59 * 1. 创建一个多部件的部件内容!MimeMultipart
60 * MimeMultipart就是一个集合,用来装载多个主体部件!
61 * 2. 我们需要创建两个主体部件,一个是文本内容的,另一个是附件的。
62 * 主体部件叫MimeBodyPart
63 * 3. 把MimeMultipart设置给MimeMessage的内容!
64 */
65 MimeMultipart list = new MimeMultipart();//创建多部分内容
66 // 创建MimeBodyPart
67 MimeBodyPart part1 = new MimeBodyPart();
68 // 设置主体部件的内容
69 part1.setContent("这是一封包含附件的邮件", "text/html;charset=utf-8");
70 // 把主体部件添加到集合中
71 list.addBodyPart(part1);
72 // 创建MimeBodyPart
73 MimeBodyPart part2 = new MimeBodyPart();
74 part2.attachFile(new File("F:/Lebron.jpeg"));//设置附件的内容
75 part2.setFileName(MimeUtility.encodeText("篮球明星.jpg"));//设置显示的文件名称,其中encodeText用来处理中文乱码问题
76 list.addBodyPart(part2);
77 msg.setContent(list);//把它设置给邮件作为邮件的内容。
78 //3. 发
79 Transport.send(msg);
80 }
81 }
应用实例2(封装工具类方式发送):

1 import java.io.File;
2 import javax.mail.Session;
3 import org.junit.Test;
4 public class Demo2 {
5 @Test
6 public void fun3() throws Exception {
7 //1. 得到session
8 Session session = MailUtils.createSession("smtp.163.com",
9 "xxx", "yyy");
10 //2. 创建邮件对象
11 Mail mail = new Mail("xxx@163.com",
12 "zzz@qq.com",
13 "测试邮件", "正文");
14 //创建两个附件对象
15 AttachBean ab1 = new AttachBean(new File("F:/Lebron.jpeg"), "小美女.jpg");
16 AttachBean ab2 = new AttachBean(new File("F:/big.jpg"), "衣服.jpg");
17 // 添加到mail中
18 mail.addAttach(ab1);
19 mail.addAttach(ab2);
20 //3. 发送
21 MailUtils.send(session, mail);
22 }
23 }

1 import java.io.File;
2
3 /*
4 * 附件类,只有文件,即附件才文件名
5 */
6 public class AttachBean {
7 private String cid;
8 private File file;
9 private String fileName;
10
11 public String getCid() {
12 return cid;
13 }
14
15 public void setCid(String cid) {
16 this.cid = cid;
17 }
18
19 public File getFile() {
20 return file;
21 }
22
23 public void setFile(File file) {
24 this.file = file;
25 }
26
27 public String getFileName() {
28 return fileName;
29 }
30
31 public void setFileName(String fileName) {
32 this.fileName = fileName;
33 }
34
35 public AttachBean() {
36
37 }
38
39 public AttachBean(File file, String fileName) {
40 super();
41 this.file = file;
42 this.fileName = fileName;
43 }
44 }

1 import java.util.ArrayList;
2 import java.util.List;
3
4 /**
5 * 表示邮件类,你需要设置:账户名和密码、收件人、抄送(可选)、暗送(可选)、主题、内容,以及附件(可选)
6 *
7 * 在创建了Mail对象之后
8 * 可以调用它的setSubject()、setContent(),设置主题和正文
9 * 也可以调用setFrom()和 addToAddress(),设置发件人,和添加收件人。
10 * 也可以调用addAttch()添加附件
11 * 创建AttachBean:new AttachBean(new File("..."), "fileName");
12 */
13 public class Mail {
14 private String from;//发件人
15 private StringBuilder toAddress = new StringBuilder();//收件人
16 private StringBuilder ccAddress = new StringBuilder();//抄送
17 private StringBuilder bccAddress = new StringBuilder();//暗送
18
19 private String subject;//主题
20 private String content;//正文
21
22 // 附件列表
23 private List<AttachBean> attachList = new ArrayList<AttachBean>();
24
25 public Mail() {}
26
27 public Mail(String from, String to) {
28 this(from, to, null, null);
29 }
30
31 public Mail(String from, String to, String subject, String content) {
32 this.from = from;
33 this.toAddress.append(to);
34 this.subject = subject;
35 this.content = content;
36 }
37
38 /**
39 * 返回发件人
40 * @return
41 */
42 public void setFrom(String from) {
43 this.from = from;
44 }
45
46 /**
47 * 返回发件人
48 * @return
49 */
50 public String getFrom() {
51 return from;
52 }
53
54 /**
55 * 返回主题
56 */
57 public String getSubject() {
58 return subject;
59 }
60
61 /**
62 * 设置主题
63 */
64 public void setSubject(String subject) {
65 this.subject = subject;
66 }
67
68 /**
69 * 获取主题内容
70 */
71 public String getContent() {
72 return content;
73 }
74
75 /**
76 * 设置主题内容
77 * @param content
78 */
79 public void setContent(String content) {
80 this.content = content;
81 }
82
83 /**
84 * 获取收件人
85 * @return
86 */
87 public String getToAddress() {
88 return toAddress.toString();
89 }
90
91 /**
92 * 获取抄送
93 * @return
94 */
95 public String getCcAddress() {
96 return ccAddress.toString();
97 }
98
99 /**
100 * 获取暗送
101 * @return
102 */
103 public String getBccAddress() {
104 return bccAddress.toString();
105 }
106
107 /**
108 * 添加收件人,可以是多个收件人
109 * @param to
110 */
111 public void addToAddress(String to) {
112 if(this.toAddress.length() > 0) {
113 this.toAddress.append(",");
114 }
115 this.toAddress.append(to);
116 }
117
118 /**
119 * 添加抄送人,可以是多个抄送人
120 * @param cc
121 */
122 public void addCcAddress(String cc) {
123 if(this.ccAddress.length() > 0) {
124 this.ccAddress.append(",");
125 }
126 this.ccAddress.append(cc);
127 }
128
129 /**
130 * 添加暗送人,可以是多个暗送人
131 * @param bcc
132 */
133 public void addBccAddress(String bcc) {
134 if(this.bccAddress.length() > 0) {
135 this.bccAddress.append(",");
136 }
137 this.bccAddress.append(bcc);
138 }
139
140 /**
141 * 添加附件,可以添加多个附件
142 * @param attachBean
143 */
144 public void addAttach(AttachBean attachBean) {
145 this.attachList.add(attachBean);
146 }
147
148 /**
149 * 获取所有附件
150 * @return
151 */
152 public List<AttachBean> getAttachs() {
153 return this.attachList;
154 }
155 }

1 import java.io.IOException;
2 import java.util.List;
3 import java.util.Properties;
4
5 import javax.mail.Authenticator;
6 import javax.mail.Message.RecipientType;
7 import javax.mail.MessagingException;
8 import javax.mail.PasswordAuthentication;
9 import javax.mail.Session;
10 import javax.mail.Transport;
11 import javax.mail.internet.InternetAddress;
12 import javax.mail.internet.MimeBodyPart;
13 import javax.mail.internet.MimeMessage;
14 import javax.mail.internet.MimeMultipart;
15 import javax.mail.internet.MimeUtility;
16
17 /**
18 * 本类只有这么一个方法,用来发邮件!
19 */
20 public class MailUtils {
21 public static Session createSession(String host, final String username, final String password) {
22 Properties prop = new Properties();
23 prop.setProperty("mail.host", host);// 指定主机
24 prop.setProperty("mail.smtp.auth", "true");// 指定验证为true
25
26 // 创建验证器
27 Authenticator auth = new Authenticator() {
28 public PasswordAuthentication getPasswordAuthentication() {
29 return new PasswordAuthentication(username, password);
30 }
31 };
32
33 // 获取session对象
34 return Session.getInstance(prop, auth);
35 }
36
37 /**
38 * 发送指定的邮件
39 *
40 * @param mail
41 */
42 public static void send(Session session, final Mail mail) throws MessagingException,
43 IOException {
44
45 MimeMessage msg = new MimeMessage(session);// 创建邮件对象
46 msg.setFrom(new InternetAddress(mail.getFrom()));// 设置发件人
47 msg.addRecipients(RecipientType.TO, mail.getToAddress());// 设置收件人
48
49 // 设置抄送
50 String cc = mail.getCcAddress();
51 if (!cc.isEmpty()) {
52 msg.addRecipients(RecipientType.CC, cc);
53 }
54
55 // 设置暗送
56 String bcc = mail.getBccAddress();
57 if (!bcc.isEmpty()) {
58 msg.addRecipients(RecipientType.BCC, bcc);
59 }
60
61 msg.setSubject(mail.getSubject());// 设置主题
62
63 MimeMultipart parts = new MimeMultipart();// 创建部件集对象
64
65 MimeBodyPart part = new MimeBodyPart();// 创建一个部件
66 part.setContent(mail.getContent(), "text/html;charset=utf-8");// 设置邮件文本内容
67 parts.addBodyPart(part);// 把部件添加到部件集中
68
69 ///////////////////////////////////////////
70
71 // 添加附件
72 List<AttachBean> attachBeanList = mail.getAttachs();// 获取所有附件
73 if (attachBeanList != null) {
74 for (AttachBean attach : attachBeanList) {
75 MimeBodyPart attachPart = new MimeBodyPart();// 创建一个部件
76 attachPart.attachFile(attach.getFile());// 设置附件文件
77 attachPart.setFileName(MimeUtility.encodeText(attach
78 .getFileName()));// 设置附件文件名
79 String cid = attach.getCid();
80 if(cid != null) {
81 attachPart.setContentID(cid);
82 }
83 parts.addBodyPart(attachPart);
84 }
85 }
86
87 msg.setContent(parts);// 给邮件设置内容
88 Transport.send(msg);// 发邮件
89 }
90 }
来源:https://www.cnblogs.com/fengmingyue/p/6082612.html
