邮件(带附件,模拟文件上传,跨服务器)发送核心代码
1.测试邮件发送附件接口
/**
* 测试邮件发送附件
* @param multipartFile
* @return
*/
@RequestMapping("/upload")
public String uploadFile(@RequestParam("uploadFile") MultipartFile multipartFile){
try {
//邮件发送
File file = MultipartFileToFile(multipartFile);
//调用邮件统一接口 发送邮件
//方案1:将file转base64来传输,同时记录文件名称
/**
* FileEntity fe = new FileEntity();
*fe.setFileName(file.getName());
*fe.setFileBase64String(FileUtil.fileToBase64(file));
**/
//方案2: 将文件上传到临时存放点,比如:阿里云的OSS服务器,直接通过接口来传输file对象不可以跨服务器,在本机服务器是可以的。
//@Async邮件发送采用异步的方式来发送
//将邮件的内容等json串做md5,可以作为唯一key,避免重复邮件的重复发送
//数据先落库,等异步处理之后,更新唯一key的成功或失败的状态
//邮件公用接口,记录发送的来源方,项目名称,业务线记录等。
return "邮件发送成功";
}catch (Exception e) {
e.printStackTrace();
return "邮件发送失败";
}
}
2.文件工具类
/**
*MultipartFile 转file工具类
**/
public static File MultipartFileToFile(MultipartFile multipartFile) {
File file = null;
//判断是否为null
if (multipartFile.equals("") || multipartFile.getSize() <= 0) {
return file;
}
//MultipartFile转换为File
InputStream ins = null;
OutputStream os = null;
try {
ins = multipartFile.getInputStream();
file = new File(multipartFile.getOriginalFilename());
os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ins != null){
try {
ins.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
import java.io.*;
import java.util.Base64;
/**
* 文件工具类
*/
public class FileUtil {
/**
* 将文件转base64字符串
* @param path
* @return
*/
public static String fileToBase64(String path) {
String base64 = null;
InputStream in = null;
try {
File file = new File(path);
in = new FileInputStream(file);
byte[] bytes=new byte[(int)file.length()];
in.read(bytes);
base64 = Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return base64;
}
/**
* 将文件转base64字符串
* @param file
* @return
*/
public static String fileToBase64(File file) {
if(file == null){
return null;
}
String base64 = null;
InputStream in = null;
try {
// File file = new File(path);
in = new FileInputStream(file);
byte[] bytes=new byte[(int)file.length()];
in.read(bytes);
base64 = Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return base64;
}
/**
* BASE64解码成File文件
* @param destPath
* @param base64
* @param fileName
*/
public static File base64ToFile(String destPath,String base64, String fileName) {
File file = null;
//创建文件目录
String filePath=destPath;
File dir=new File(filePath);
if (!dir.exists() && !dir.isDirectory()) {
dir.mkdirs();
}
BufferedOutputStream bos = null;
java.io.FileOutputStream fos = null;
try {
byte[] bytes = Base64.getDecoder().decode(base64);
file=new File(filePath+"/"+fileName);
fos = new java.io.FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
}
3.实体类
//FileEntity对象
public class FileEntity {
private String fileBase64String;
private String fileName;
public String getFileBase64String() {
return fileBase64String;
}
public void setFileBase64String(String fileBase64String) {
this.fileBase64String = fileBase64String;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
4.邮件发送service类
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
//邮件发送带附件的工具类
@Service
public class EmailMultiService {
private static Logger logger = LoggerFactory.getLogger(EmailMultiService.class);
public static MailAuthenticator authenticator;
private MimeMessage message;
private Session session;
private Transport transport;
private Properties properties = new Properties();
//apollo配置
@Value("${apollo.server.host}")
private String mailHost = null;
@Value("${apollo.from.addr}")
private String sender_username = null;
@Value("${apollo.email.password}")
private String sender_password = null;
/**
* 构造方法
*/
public EmailMultiService() {
super();
}
/**
* 主方法
*/
public String sendEmail(String[] receivers,String[] receiversCC,String title, String content,List
try {
// 初始化smtp发送邮件所需参数
initSmtpParams();
// 发送邮件
doSendHtmlEmail(receivers, receiversCC, title, content, fileList,md5);
} catch (Exception e) {
logger.error("sendEmail multi异常:",e);
return "";
}
return "success";
}
/**
* 初始化smtp发送邮件所需参数
*/
private boolean initSmtpParams() {
properties.put("mail.smtp.host", mailHost);// mail.envisioncitrix.com
properties.put("mail.smtp.auth", "true");
properties.put("mail.transport.protocol", "smtp");
//端口 重要,默认是25端口
properties.put("mail.smtp.port", "465");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.ssl.checkserveridentity", "false");
properties.put("mail.smtp.ssl.trust", mailHost);
//重要
properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
authenticator = new MailAuthenticator(sender_username, sender_password);
session = Session.getInstance(properties, authenticator);
session.setDebug(false);// 开启后有调试信息
message = new MimeMessage(session);
return true;
}
/**
* 发送邮件
*/
private boolean doSendHtmlEmail(String[] toEmial,String[] toCcEmial,String title, String htmlContent, List
try {
// 发件人
InternetAddress from = new InternetAddress(sender_username);
message.setFrom(from);
// 收件人(多个) 数组方式
for (String sendTo : toEmial) {
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(sendTo));
}
// 设置抄送:抄送地址必须满足标准email地址格式,否则报错
//可选
if(toCcEmial != null && toCcEmial.length > 0) {
for (String copy : toCcEmial) {
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(copy));
}
}
// 邮件主题
message.setSubject(title);
// 添加邮件的各个部分内容,包括文本内容和附件
Multipart multipart = new MimeMultipart();
// 添加邮件正文
BodyPart cOntentPart= new MimeBodyPart();
contentPart.setContent(htmlContent, "text/html;charset=UTF-8");
multipart.addBodyPart(contentPart);
// 遍历添加附件
if (fileList != null && fileList.size() > 0) {
//转换文件操作
List
//按上传日期来上传目录 文件路径
Long today = Long.parseLong(DateFormatUtils.format(new Date(), "yyyyMMdd").trim());
String destPath = "/usr/local/email/"+ String.valueOf(today) +"/" + md5 + "/";
for (FileEntity fileEntity : fileList) {
File f = FileUtil.base64ToFile(destPath,fileEntity.getFileBase64String(),fileEntity.getFileName());
files.add(f);
}
//封装成附件的方式
for (File file : files) {
if(file != null) {
BodyPart attachmentBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(file);
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName(file.getName());
multipart.addBodyPart(attachmentBodyPart);
}
}
}
// 将多媒体对象放到message中
message.setContent(multipart);
// 保存邮件
message.saveChanges();
// SMTP验证,就是你用来发邮件的邮箱用户名密码
transport = session.getTransport("smtp");
transport.connect(mailHost, sender_username, sender_password);
// 发送邮件
transport.sendMessage(message, message.getAllRecipients());
logger.info(title + " Email send success!");
} catch (Exception e) {
logger.error("发送附件邮件异常:",e);
} finally {
if (transport != null) {
try {
transport.close();
} catch (MessagingException e) {
logger.error("finally发送附件邮件异常:",e);
}
}
}
return true;
}
}
//普通邮件发送,不带附件的方式
public String sendEmail(String[] toEmial, String[] toCcEmial, String subject, String content) {
try {
HtmlEmail simpleEmail = new HtmlEmail();
simpleEmail.setHostName(mailHost);
simpleEmail.setAuthentication(sender_username, sender_password);
simpleEmail.setFrom(sender_username, sender_username);
simpleEmail.addTo(toEmial);
if (toCcEmial != null) {
simpleEmail.addCc(toCcEmial);
}
simpleEmail.setSubject(subject);
simpleEmail.setMsg(content);
//add
simpleEmail.setSSLOnConnect(true);
simpleEmail.setCharset(StandardCharsets.UTF_8.name());
return simpleEmail.send();
} catch (Exception e) {
logger.error("发送邮件02异常:", e);
}
return null;
}