目录
一、相关概念
Email就是电子邮件。一般邮件软件我们称为MUA:Mail User Agent,意思是给用户服务的邮件代理;邮件服务器则称为MTA:Mail Transfer Agent,意思是邮件中转的代理;最终到达的邮件服务器称为MDA:Mail Delivery Agent,意思是邮件到达的代理。电子邮件一旦到达MDA,就不再动了。
我们不关心这些服务器内部是如何运行的。要发送邮件,我们关心的是如何编写一个MUA的软件,把邮件发送到MTA上。MUA到MTA发送邮件的协议就是SMTP协议,它是Simple Mail Transport Protocol的缩写,使用标准端口25,也可以使用加密端口465或587。SMTP协议是一个建立在TCP之上的协议,任何程序发送邮件都必须遵守SMTP协议。使用Java程序发送邮件时,我们无需关心SMTP协议的底层原理,只需要使用JavaMail这个标准API就可以直接发送邮件。
常用邮件服务商的SMTP信息:标准端口25
●QQ邮箱:SMTP服务器是smtp.qq.com,端口是465/587
●163邮箱:SMTP服务器是smtp.163.com,端口是465
●Gmail邮箱:SMTP服务器是smtp.gmail.com,端口是465/587
二、 准备SMTP登录信息
以网易邮箱为例:
登录邮箱,在设置中选择开启POP3/SMTP服务
下滑在授权密码管理中选择新增授权密码,按要求操作,获取新密码。
准备好信息后,在程序中导入javax.mail-1.6.2.jar包。
然后,我们通过JavaMail API连接到SMTP服务器上:以587端口为例,连接SMTP服务器时,需要准备一个Properties对象,填入相关信息。最后获取Session实例时,如果服务器需要认证,还需要传入一个Authenticator对象,并返回指定的用户名和口令。
//写在工具类中方便直接调用,复用
public class JavaMailUtils {
private JavaMailUtils(){
}
public static Session createeSession() {
//邮箱账号信息
String userName = "m18220487260@163.com";//邮箱账号
String password = "NR*********ABILH";//授权密码
//SMTP服务器连接信息
Properties props = new Properties();
props.put("mail.smtp.host","smtp.163.com");//主机名
props.put("mail.smtp.port","25");//端口
props.put("mail.smtp.auth","true");//是否需要用户认证
props.put("mail.smtp.starttls.enable","true");//启用TLS加密
//创建Session会话
//参数1:smtp服务器连接参数
//参数2:账号和密码认证对象
Session session = Session.getInstance(props,new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
});
session.setDebug(true);
return session;
}
}
三、发送邮件
1、简单文本内容
try {
//创建session会话对象
Session session = JavaMailUtils.createeSession();
//创建邮箱对象
MimeMessage message = new MimeMessage(session);
//邮件标题
message.setSubject("这是一首诗");
//简单文本内容
message.setText("我自横刀向天笑,去留肝胆两昆仑");
//发件地址
message.setFrom("**********@163.com");
//收件地址 单指(RecipientType.TO收件人)
message.setRecipient(RecipientType.TO, new InternetAddress("*******@qq.com"));
//发送
Transport.send(message);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2、带有html标签的文本内容(且抄送,通俗理解群发)
try {
message.setFrom(new InternetAddress("m18220487260@163.com"));
message.setRecipient(RecipientType.TO, new InternetAddress("@qq.com"));
//RecipientType.CC(抄送给可多人)
message.setRecipients(RecipientType.CC, new InternetAddress[] {new InternetAddress("@qq.com"),new InternetAddress("@qq.com")});
message.setSubject("这是一句诗");
//正文
message.setText("<b>我自横刀向天笑,去留肝胆两昆仑</b>","utf-8","html");
//发送
Transport.send(message);
}
3、带有附件的邮件
//需要传多个内容时需要使用BodyPart对象。
//创建正文对象
BodyPart textPart = new MimeBodyPart();
//输出正文
textPart.setContent("<b>我自横刀向天笑,去留肝胆两昆仑</b>","text/html;charset=utf-8");
//创建附件对象
BodyPart filepart = new MimeBodyPart();
//设置附件显示名称
filepart.setFileName("薛之谦");
//上传附件
filepart.setDataHandler(new DataHandler(new ByteArrayDataSource(Files.readAllBytes
(Paths.get("C:\\Users\\GAN\\Desktop\\1\\薛之谦.jpg")), "application/octet-stream")));
//将正文与附件组成Multipart对象
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(filepart);
//将对象放入邮件
message.setContent(multipart);
//发送
Transport.send(message);
4、发送内嵌图片的HTML邮件
即将附件图片显示在正文框中。<img src="http://example.com/test.jpg">,这样的外部图片链接通常会被邮件客户端过滤,并提示用户显示图片并不安全。只有内嵌的图片才能正常在邮件中显示。所以,这种方式并不推荐。
//创建正文对象
BodyPart textPart = new MimeBodyPart();
StringBuilder contentText = new StringBuilder();
//<h3>html语言中的三级标题
contentText.append("<h3>薛之谦</h3>");
contentText.append("<b>陌上人似玉,君子世无双</b>");
//利用设置的图片ID拼接图片
contentText.append("<img src=\"cid:xue\"/>");
textPart.setContent(contentText.toString(),"text/html;charset=utf-8");
//创建附件对象
BodyPart imagepart = new MimeBodyPart();
imagepart.setDataHandler(new DataHandler(new ByteArrayDataSource(Files.readAllBytes
(Paths.get("目标图片地址")), "application/octet-stream")));
//设置上传图片的ID
imagepart.setHeader("Content-ID", "xue");
//将正文与附件组成Multipart对象
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(imagepart);
//将对象放入邮件
message.setContent(multipart);
//发送
Transport.send(message);
总结:
1、MTP协议是一个建立在TCP之上的协议,任何程序发送邮件都必须遵守SMTP协议。
2、在用Java程序发送邮件前需要准备SMTP登录信息并导包
3、但文本内容可直接使用message.setText()方法,多内容更推荐使用BodyPart对象。
4 、发送内嵌图片的邮件时,使用imagepart.setHeader()方法设置图片ID,拼接入正文中。