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加密,不使用内部邮箱不用端口时,可以不打开sslSession 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>