email邮件(带附件,模拟文件上传,跨服务器)发送核心代码 Couldn't connect to host, port: smtp.163.com, 25; timeout -1;
邮件(带附件,模拟文件上传,跨服务器)发送核心代码
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<FileEntity> fileList,String md5) { 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端口 Couldn't connect to host, port: smtp.163.com, 25; timeout -1; 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<FileEntity> fileList,String md5) { try { // 发件人 InternetAddress from = new InternetAddress(sender_username); message.setFrom(from); // 收件人(多个) 数组方式,会覆盖掉,最终是发送最后一个邮箱地址 //for (String sendTo : toEmial) { // message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(sendTo)); //}
InternetAddress[] address = new InternetAddress[toEmial.length];
for (int i = 0; i < toEmial.length; i++) {
String sendTo = toEmial[i];
InternetAddress addr = new InternetAddress(sendTo);
address[i] = addr;
}
message.setRecipients(Message.RecipientType.TO, address);
// 设置抄送:抄送地址必须满足标准email地址格式,否则报错 //可选 if(toCcEmial != null && toCcEmial.length > 0) { //for (String copy : toCcEmial) { // message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(copy)); //}
InternetAddress[] addressCC = new InternetAddress[toCcEmial.length];
for (int i = 0; i < toCcEmial.length; i++) {
String sendTo = toCcEmial[i];
InternetAddress addr = new InternetAddress(sendTo);
addressCC[i] = addr;
}
message.setRecipients(Message.RecipientType.CC, addressCC);
} // 邮件主题 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<File> files = new ArrayList<>(); //按上传日期来上传目录 文件路径 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("发送邮件异常:", e); } return null; }
浙公网安备 33010602011771号