邮件协议
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_52 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来处理。 第一步:获得SessionSession 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 @Test17 public void fun1() throws Exception {18 //1. 得到session19 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 @Override24 protected PasswordAuthentication getPasswordAuthentication() {25 return new PasswordAuthentication("xxx", "yyy");//注意:该密码为授权码26 }27 };28 Session session = Session.getInstance(props, auth);29 //2. 创建MimeMessage30 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 @Test40 public void fun2() throws Exception {41 //1. 得到session42 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 @Override47 protected PasswordAuthentication getPasswordAuthentication() {48 return new PasswordAuthentication("xxx", "yyy");49 }50 };51 Session session = Session.getInstance(props, auth);52 //2. 创建MimeMessage53 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. 创建一个多部件的部件内容!MimeMultipart60 * MimeMultipart就是一个集合,用来装载多个主体部件!61 * 2. 我们需要创建两个主体部件,一个是文本内容的,另一个是附件的。62 * 主体部件叫MimeBodyPart63 * 3. 把MimeMultipart设置给MimeMessage的内容!64 */65 MimeMultipart list = new MimeMultipart();//创建多部分内容66 // 创建MimeBodyPart67 MimeBodyPart part1 = new MimeBodyPart();68 // 设置主体部件的内容69 part1.setContent("这是一封包含附件的邮件", "text/html;charset=utf-8");70 // 把主体部件添加到集合中71 list.addBodyPart(part1);72 // 创建MimeBodyPart73 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 ListattachList = new ArrayList (); 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 * @return102 */103 public String getBccAddress() {104 return bccAddress.toString();105 }106 107 /**108 * 添加收件人,可以是多个收件人109 * @param to110 */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 cc121 */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 bcc132 */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 attachBean143 */144 public void addAttach(AttachBean attachBean) {145 this.attachList.add(attachBean);146 }147 148 /**149 * 获取所有附件150 * @return151 */152 public List 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");// 指定验证为true25 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 mail41 */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 ListattachBeanList = 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(attach78 .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 }