JAVA邮件发送的大致过程是这样的的:
1、构建一个properties文件,该文件中存放SMTP服务器地址等参数。
2、通过构建的properties文件和javax.mail.Authenticator具体类来创建一个javax.mail.Session。Session的创建,就相当于登录邮箱一样。剩下的自然就是新建邮件。
3、构建邮件内容,一般是javax.mail.internet.MimeMessage对象,并指定发送人,收信人,主题,内容等等。
4、使用javax.mail.Transport工具类发送邮件。
以163邮箱为例,获取邮箱授权码步骤:
- 点击上方设置按钮,再点击POP3/SMTP/IMAP。
- 开启对应服务授权码,需要发送短信开启,只显示一次。
- 下面有对应的服务器地址、授权码管理,如果不用可以删除。
SMTP服务器地址:一般是 smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。
SMTP协议:通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。
POP3协议:通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。
代码实现:
//文件暂存地址
@Value("D:/file/tmp")
private String fileTmp;
//发送人邮箱
@Value("xxxxxxxx@163.com")
private String senderEmail;
//发送人邮箱授权码
@Value("ACJGFOSNF9866GFF")
private String senderCode;
//服务器地址
@Value("smtp.163.com")
private String emailSMTPHost;
//端口 只有使用内部邮箱时才会使用端口
//@Value("465")
//private Integer emailSMTPPort;
//收件人邮箱
@Value("xxxxxxx@163.com")
private String receiveMailAccount;
//抄送人邮箱
@Value("xxxxxxx@163.com")
private String ccMailAccount;
@Value("xxxxxxx@qq.com")
private String ccMailAccount1;
@Value("xxxxxxx@qq.com")
private String ccMailAccount2;
/**
* 发送邮件内容
*
* @param file 邮件内容
*/
@PostMapping("sendMessage")
public Result sendMessage(@RequestParam("file") MultipartFile file) {
log.info("开始发送邮件! 文件名称:{}",file.getOriginalFilename());
//抄送人
Vector<String> toList = new Vector<>() ;
toList.addElement(ccMailAccount);
toList.addElement(ccMailAccount1);
toList.addElement(ccMailAccount2);
String res = EmailUtils.sendMail(file, fileTmp, senderEmail, senderCode, emailSMTPHost,
receiveMailAccount, toList,emailSMTPPort);
if (!res.equals("success")){
return Result.create("邮件发送失败!",ResultCode.NFC_FAILURE);
}
return Result.create("邮件发送成功!",ResultCode.SUCCESS);
}
MIME(多用途互联网邮件扩展类型)
MimeBodyPart类
javax.mail.internet.MimeBodyPart类
表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。MimeMultipart类
javax.mail.internet.MimeMultipart是抽象类
Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象
package .xxxx.util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
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 java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;
@Slf4j
public class EmailUtils {
/**
* 发送邮件
* @param file 邮件内容
*
*/
public static String sendMail(MultipartFile file, String fileTmp, String senderEmail, String senderCode,
String emailSMTPHost, String receiveMailAccount, Vector<String> toList,
Integer emailSMTPPort) {
try {
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");// 使用的协议
props.setProperty("mail.smtp.host", emailSMTPHost);// 发件人的邮箱的SMTP服务器地址
//props.setProperty("mail.smtp.port", String.valueOf(emailSMTPPort));//只有内部邮箱才会使用端口,默认为25,加密为465 不建议使用默认
props.setProperty("mail.smtp.auth", "true");// 需要请求认证
//props.setProperty("mail.smtp.ssl.enable", "true");//开启ssl加密,不使用内部邮箱不用端口时,可以不打开ssl
Session session = Session.getInstance(props);//得到会话对象实例
session.setDebug(false);//是否打印详细日志
MimeMessage message = createMimeMessage(session, file,senderEmail,receiveMailAccount,
fileTmp, toList);//获取邮件对象(封装了一个方法)
Transport transport = session.getTransport();
transport.connect(senderEmail, senderCode);//连接发送人的邮箱账户
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
// 7. 关闭连接
transport.close();
//删除临时存放文件
FileUtils.deleteFolder(fileTmp);
log.info("邮件发送成功");
return "success";
} catch (Exception e) {
log.error("发送邮件失败");
}
return "";
}
/**
* 创建发送邮件内容
* @param session session
* @param mainFile 邮件附件
*/
private static MimeMessage createMimeMessage(Session session, MultipartFile mainFile,
String senderEmail, String receiveMailAccount,
String fileTmp,Vector<String> toList) {
MimeMessage message = null;
try {
// 1. 创建一封邮件
message = new MimeMessage(session);
// 2. From: 发件人
message.setFrom(new InternetAddress(senderEmail, "发件人", "UTF-8"));
// 3. 设置收件人、抄送人、密送人
//MimeMessage.RecipientType.TO:收件类型;MimeMessage.RecipientType.CC:抄送类型;MimeMessage.RecipientType.BCC:密送类型
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMailAccount, "收件人", "UTF-8"));
InternetAddress[] addArr = null;
// 设置抄送人地址
if ((toList != null) && (toList.size() != 0)) {
addArr = new InternetAddress[toList.size()];
for (int i = 0; i < toList.size(); i++) {
String ccMailStr = toList.get(i);
addArr[i] = new InternetAddress(ccMailStr);
}
message.setRecipients(Message.RecipientType.CC, addArr); // 设置抄送人地址
}
// message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(ccMailAccount, "抄送人", "UTF-8"));
// message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(bccmailAccount, "密送人", "UTF-8"));
// 4. Subject: 邮件主题
message.setSubject("这是邮件主题!", "UTF-8");
// 5. Content: 邮件正文(可以使用html标签)
//一个Multipart对象包含一个或多个bodypart对象,组成邮件正文
MimeMultipart multipart = new MimeMultipart();
MimeBodyPart contentPart = new MimeBodyPart();
contentPart.setText("这是邮件正文","UTF-8");
contentPart.setHeader("Content-Type", "text/html; charset=UTF-8");
multipart.addBodyPart(contentPart);
MimeBodyPart filePart = new MimeBodyPart();
File file = MultipartFileToFile(mainFile,fileTmp);
if (!ObjectUtils.isEmpty(file)){
DataHandler handler = new DataHandler(new FileDataSource(file));
filePart.setDataHandler(handler);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String formatDate = sdf.format(new Date());
String name = file.getName();
String suffix = name.substring(name.lastIndexOf("."));
//对文件名进行编码,防止出现乱码
String fileName = "这是附件名称"+formatDate+suffix;
filePart.setFileName(fileName);
multipart.addBodyPart(filePart);
message.setContent(multipart);
// 6. 设置发件时间
message.setSentDate(new Date());
// 7. 保存设置
message.saveChanges();
}
} catch (Exception e) {
e.printStackTrace();
log.error("创建发送邮件内容失败!", e);
}
return message;
}
/**
* 将MultipartFile转换为File
* @param multiFile multiFile
* @return file
*/
public static File MultipartFileToFile(MultipartFile multiFile,String fileTmp) {
File directory = new File(fileTmp);
if (!directory.exists()) {
directory.mkdirs();
}
// 获取文件名
String fileName = multiFile.getOriginalFilename();
// 获取文件后缀
if(!StringUtils.isEmpty(fileName)){
String prefix = fileName.substring(fileName.lastIndexOf("."));
// 若须要防止生成的临时文件重复,能够在文件名后添加随机码
try {
File file = File.createTempFile(String.valueOf(System.currentTimeMillis()), prefix, new File(fileTmp));
multiFile.transferTo(file);
return file;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
pom文件依赖:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>