maven依赖
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
1、controller
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.mail.internet.MimeMessage;
import javax.validation.Valid;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api/v*/personal/mail")
public class MailController extends BaseController {
@Autowired
private MailService mailService;
@Value("${pm.mail.attachment.temp}")
private String prefix;
/**
* 发送邮件
*/
@PostMapping("/send")
public Result send(@Valid MailProtocol.Send.Input input, List<MultipartFile> file, BindingResult bindingResult) {
validateArgs(bindingResult);
List<String> filesPath = getFilesPath(file);
mailService.sendMail(StringUtil.join(input.getTo(), ","), StringUtil.join(input.getCc(), ","),
StringUtil.join(input.getBcc(), ","), input.getSubject(), input.getContent(), filesPath);
return succeed();
}
/**
* 暂存文件
*
* @param attachments 附件
* @return 附件路径
*/
private List<String> getFilesPath(List<MultipartFile> attachments) {
if (isEmpty(attachments)) {
return new ArrayList<>();
}
List<String> filesPath = new ArrayList<>(attachments.size());
String path = prefix + uuid() + "/";
File root = new File(path);
if (!root.exists()) {
root.mkdirs();
}
try {
for (MultipartFile file : attachments) {
String filePath = path + file.getOriginalFilename();
filesPath.add(filePath);
IOUtils.copy(file.getInputStream(), new FileOutputStream(filePath));
}
} catch (IOException e) {
if (logger.isInfoEnabled()) {
logger.info("[save temp file error]========{}", e.getMessage());
}
}
return filesPath;
}
}
2、service
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Properties;
/**
* @ Author:yl1794
* @ Date:2019/10/29 9:03
* @ Description:邮件服务
*/
@Service
public class MailService extends BaseService {
@Value("${pm.mail.sender.username}")
private String username;
@Value("${pm.mail.sender.password}")
private String password;
@Value("${pm.mail.smtp.host}")
private String host;
@Value("${pm.mail.smtp.port}")
private int port;
@Async
public void sendMail(String to, String cc, String bcc, String subject, String content, List<String> attachments) {
if(logger.isInfoEnabled()){
logger.info("[SEND_MAIL]========to: {}, cc: {}, bcc: {}, attachments: {}", to, cc, bcc, attachments);
}
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.checkserveridentity", "false");
props.put("mail.smtp.ssl.trust", host);
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = getMimeMessage(session, to, cc, bcc, subject, content, attachments);
// 发送邮件
Transport.send(message);
} catch (MessagingException | IOException e) {
throwInternalServerException(e.getMessage());
} finally {
if (isNotEmpty(attachments)) {
delTmpFiles(attachments.get(0));
}
}
}
/**
* 创建邮件的实例对象
*
* @param session session对象
* @param to 发送人
* @param cc 抄送人
* @param bcc 密送人
* @param subject 主题
* @param content 内容
* @param attachments 附件
* @return MimeMessage
* @throws javax.mail.MessagingException
* @throws IOException
*/
private MimeMessage getMimeMessage(Session session, String to, String cc, String bcc, String subject, String content,
List<String> attachments)
throws javax.mail.MessagingException, IOException {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
// 发件人别名设置
// message.setFrom(new InternetAddress(MimeUtility.encodeText("我的昵称") + " <" + username + ">"));
// message.setFrom(new InternetAddress(username,"我的昵称", "UTF-8"));
// TO:发送、CC:抄送、BCC :密送
if (isNotEmpty(to)) {
message.setRecipients(Message.RecipientType.TO, new InternetAddress().parse(to));
}
if (isNotEmpty(cc)) {
message.setRecipients(Message.RecipientType.CC, new InternetAddress().parse(cc));
}
if (isNotEmpty(bcc)) {
message.setRecipients(Message.RecipientType.BCC, new InternetAddress().parse(bcc));
}
message.setSubject(subject, "UTF-8");
//添加邮件的各个部分内容,包括文本内容和附件
MimeMultipart multipart = new MimeMultipart();
//设置邮件正文
MimeBodyPart contentPart = new MimeBodyPart();
contentPart.setContent(content, "text/html;charset=utf-8");
multipart.addBodyPart(contentPart);
// 添加附件
addAttachments(multipart, attachments);
message.setContent(multipart);
message.saveChanges();
return message;
}
/**
* 添加附件(多个)
*
* @param multipart multipart
* @param files 文件路径
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
private void addAttachments(MimeMultipart multipart, List<String> files) throws MessagingException, IOException {
if (isEmpty(files)) {
return;
}
for (String file : files) {
MimeBodyPart messageBodyPart = new MimeBodyPart();
DataHandler dataHandler = new DataHandler(new FileDataSource(file));
messageBodyPart.setDataHandler(dataHandler);
messageBodyPart.setFileName(MimeUtility.encodeText(dataHandler.getName()));
multipart.addBodyPart(messageBodyPart);
}
}
// private void addAttachments(MimeMultipart multipart, List<MultipartFile> files) throws MessagingException, IOException {
//
// if (isEmpty(files)) {
// return;
// }
//
// for (MultipartFile file : files) {
// MimeBodyPart messageBodyPart = new MimeBodyPart();
// ByteArrayDataSource dataSource = new ByteArrayDataSource(file.getInputStream(), file.getContentType());
// DataHandler dataHandler = new DataHandler(dataSource);
// messageBodyPart.setDataHandler(dataHandler);
// messageBodyPart.setFileName(MimeUtility.encodeText(dataHandler.getName()));
// multipart.addBodyPart(messageBodyPart);
// }
// }
/**
* 删除某个文件的父目录下所有文件(包括文件夹)
*
* @param filePath filePath
* @throws IOException
*/
private void delTmpFiles(String filePath) {
if (isEmpty(filePath)) {
return;
}
File file = new File(filePath);
try {
FileUtils.deleteDirectory(file.getParentFile());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
MailService mailService = new MailService();
// mailService.sendMail("cqh@xxx.com,cqh@xxx.com", null, null, "主题test", "内容test444!", null);
}
}
附:
邮件的抄送,密送的区别:
1、抄送就是将邮件同时发送给收信人以外的人,用户所写的邮件抄送一份给别人,对方可以看见该用户的E-mail。
2、密送,只有发信的人知道密送给了谁,邮件接收者和抄送者都不知道发送者密送给了谁,但是接收密送的人知道是谁给他发的这封邮件,以及这份邮件本来发给了谁,并抄送给了谁,但不知道这封邮件同时又密送给了谁。
3、如A 发送邮件给B1、B2、B3,抄送给C1、C2、C3,密送给D1、D2、D3。
那么:
A知道自己发送邮件给了B1、B2、B3,并且抄送给了C1、C2、C3,密送给了D1、D2、D3。
B1知道这封是A发送给B1、B2、B3的邮件,并且抄送给了C1、C2、C3,但不知道密送给了D1、D2、D3。
C1知道这封是A发送给B1、B2、B3的邮件,并且抄送给了C1、C2、C3,但不知道密送给了D1、D2、D3。
D1知道这封是A发送给B1、B2、B3的邮件,并且抄送给了C1、C2、C3,而且密送给了自己,但不知道密送给了D2、D3。