Email即"电子邮件",日常生活中我们所熟悉的邮箱地址有@162.com,@qq.com等,在Java中,我们也可以收发电子邮件。
电子邮件的发送过程类似与我们去邮局送信,首先我们使用一些电子邮件软件(也称为MUA:Mail User Agent)完成自己要送出的电子邮件书写,再将电子邮件交给邮件服务器MTA:Mail Transfer Agent)进行电子邮件的中转,邮件服务器会再将你的电子邮件送到送达邮件服务器MDA(Mail Delivery Agent),最后由收件人在收件箱中查看你发出的电子邮件。
在整个电子邮件发送的过程中,MTA和MDA都是现成的服务器软件,所以我们只需要关心如何编写一个MUA的软件,将邮件发送到MTA中。MUA和MTA之间进行发送邮件的协议是SMTP协议,SMTP协议是建立在TCP协议上的协议,任何程序发送邮件都必须遵守SMTP协议。在JAVA中,我们要发送邮件时,不需要关心SMTP底层的原理,只需使用JavaMail这个标准的API即可直接发送邮件。
要使用JavaMail,我们首先要准备SMTP的登陆信息,发送邮件之前我们要先确认作为MTA的邮件服务器的邮件服务器地址和端口号,我使用的是:
163邮箱:SMTP服务器是smtp.163.com,端口是465
准备好SMTP的信息后,我们导入JavaMail的jar包,然后通过JavaMail API连接到SMTP服务器上(如下代码演示)。
//邮箱账号信息
String userName="gxtututu@163.com";//邮箱发送账号
String password="HHLOWKOLYGLYYUQC";//账号授权密码
//SMTP服务器连接信息
Properties props=new Properties();
props.put("mail.smtp.host", "smtp.163.com");//SMTP主机名
props.put("mail.smtp.port", "465");//主机端口号
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);
}
});
//设置debug模式方便调试
session.setDebug(true);
在完成对SMTP的连接后,我们将连接操作封装成一个独立的类JavaMailUtils方便后续使用,在封装时使用final关键字使我们自己的工具类不能被随意修改,另外在这个类中添加一个私有的无参构造方法,确保不能被随便创建对象。(代码参考如下)
public final class JavaMailUtils {
private JavaMailUtils() {}
public static Session createSession() {
//邮箱账号信息
String userName="gxtututu@163.com";//邮箱发送账号
String password="HHLOWKOLYGLYYUQC";//账号授权密码
//SMTP服务器连接信息
Properties props=new Properties();
props.put("mail.smtp.host", "smtp.163.com");//SMTP主机名
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);
}
});
return session;
}
}
完成基本和SMTP的连接后,我们就可以进行邮件的发送了。在发送邮件时,我们需要创建一个message对象,然后调用Transport.send(Message)即可完成发送。具体发送操作如下代码:
try {
//1.创建Session会话
Session session = JavaMailUtils.createSession();
//2.创建MimeMessage邮件对象
MimeMessage message = new MimeMessage(session);
//设置邮件标题
message.setSubject("测试");
//设置邮件正文
message.setText("今天是个好日子","utf-8");
//发件人
message.setFrom(new InternetAddress("gxtututu@163.com"));
//收件人
message.setRecipient(RecipientType.TO, new InternetAddress("2606077670@qq.com"));
//抄送
message.setRecipients(RecipientType.CC, new InternetAddress[] {new InternetAddress("1372793654@qq.com"),
new InternetAddress("3213141830@qq.com")});
//3.发送邮件
Transport.send(message);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
有时候我们会发送一些HTML的内容而不是普通的文本内容,这个时候我们只需要把
message.setText("今天是个好日子","utf-8");
修改成:
message.setText("今天是个<b>好日子</b>","utf-8","html");
即可按照HTML格式显示相应的邮件内容。
除了发送一些内容时,有的邮件还会携带一些附件发送,这个时候我们就不能够直接调用message.setText()方法,而是要构造一个Multipart对象:
一个Multipart对象中可以添加若干个BodyPart,其中第一个BodyPart是邮件正文,后面的BodyPart是附件。BodyPart使用setContent()来决定要添加的内容,如果添加的是文本内容,则用setContent("...", "text/plain;charset=utf-8")添加纯文本;或者使用setContent("...", "text/html;charset=utf-8")添加HTML文本;如果添加附件,使用setFileName()来设置文件,并且添加一个setDataHandler(),传入文件的MIME类型。二进制文件可以用application/octet-stream,Word文档则是application/msword。
最后,再将Mulitipart通过setContent()放入message中,然后完成发送。
//正文
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:\\text\\temp\\temp\\c.jpg")),
"application/octet-stream")));
//将正文+附件组装成Multipart对象
Multipart multipart=new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(filePart);
//将Multipart对象放入邮件
message.setContent(multipart);
//发送邮件
Transport.send(message);
除此之外,我们有时会需要将一些图片放到邮件的正文中而不是以附件的形式发送,这种情况我们需要做一点额外的处理。
try {
Session session = JavaMailUtils.createSession();
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("gxtututu@163.com"));
message.setRecipient(RecipientType.TO, new InternetAddress("2606077670@qq.com"));
message.setSubject("测试");
//正文
BodyPart textPart=new MimeBodyPart();
//使用StringBuilder对需要的内容进行拼接
StringBuilder contentText=new StringBuilder();
contentText.append("<h3>美</h3>");
contentText.append("<p>gogogo</p>");
//添加一个<img>标签将附件显示在正文中
contentText.append("<img src=\"cid:666\"/>");
textPart.setContent(contentText.toString(), "text/html;charset=utf-8");
//附件
BodyPart imagePart=new MimeBodyPart();
imagePart.setDataHandler(
new DataHandler(
new ByteArrayDataSource(
Files.readAllBytes(Paths.get("C:\\text\\temp\\temp\\c.jpg")),
"application/octet-stream")));
//给图片设置"Content-ID"属性
imagePart.setHeader("Content-ID", "666");
//将正文+附件组装成Multipart对象
Multipart multipart=new MimeMultipart();
multipart.addBodyPart(textPart);
multipart.addBodyPart(imagePart);
//将Multipart对象放入邮件
message.setContent(multipart);
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}