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;
}
email邮件(带附件,模拟文件上传,跨服务器)发送核心代码 Couldn't connect to host, port: smtp.163.com, 25; timeout -1;的更多相关文章
- Fiddler2 模拟文件上传
最近遇到一个需求,需要上传音频文件, 服务端使用webService 通过spring3 进行文件上传.代码完成后使用 html 通过post 方式请求接口成功了,但不知道如何使用Fiddler2工具 ...
- Silverlight 2中实现文件上传和电子邮件发送
Silverlight 2中实现文件上传和电子邮件发送 [收藏此页] [打印] 作者:IT168 TerryLee 2008-05-30 内容导航: 使用Web Service上传文件 [I ...
- Linux 文件上传Linux服务器
进入命令行 在图形化桌面出现之前,与Unix系统进行交互的唯一方式就是借助由shell所提供的文本命令行界面(command line interface,CLI).CLI只能接受文本输入,也只能显示 ...
- Java实现文件上传到服务器(FTP方式)
Java实现文件上传到服务器(FTP方式) 1,jar包:commons-net-3.3.jar 2,实现代码: //FTP传输到数据库服务器 private boolean uploadServer ...
- 基于paramiko将文件上传到服务器上
通过安装使用paramiko模块,将本地文件上传到服务器上 import paramiko import datetime import os hostname = '服务器ip' username ...
- ubuntu中将本地文件上传到服务器
(1)在本地的终端下,而不是在服务器上.在本地的终端上才能将本地的文件拷入服务器. (2) scp -r localfile.txt username@192.168.0.1:/home/userna ...
- 一、手把手教你docker搭建fastDFS文件上传下载服务器
在搭建fastDFS文件上传下载服务器之前,你需要准备的有一个可连接的linux服务器,并且该linux服务器上已经安装了docker,若还有没安装docker的,先百度自行安装docker. 1.执 ...
- Vditor文件上传跨域
Vditor文件上传跨域 官网是发了一次请求,而我这里发了两次请求. 有一个option请求,形成了跨域. 虽然我在后端配置了允许跨域,但事实上,我用JWT的拦截器把文件上传的接口给拦截了. 且走的是 ...
- Jmeter之模拟文件上传、下载接口操作
上周群里有位同学,问我用jmeter怎么上传文件?因好久没用jmeter了,顺便自己也复习下,现整理出来和大家分享 一.准备工作: 上传接口一个(自行开发解决了) 下载接口 ps:没有困难创造困难也要 ...
- 一篇文章,学会jmeter模拟文件上传、下载操作
最近很多同学都在问jmeter上传,下载文件的脚本怎么做? 正巧这阵子忙完有时间,就来“折腾”一番,哈哈 现整理出来和大家分享 到底该怎么做? 一.准备工作: 上传接口一个(自行开发解决了) 下载接口 ...
随机推荐
- [Go] Go Module 私有依赖包的管理
一些自研开发的第三方包,特别是一些业务依赖包,是不允许公开下载的(私有库),并且版本库也可能不支持HTTPS协议, 因此无法使用 go get 或者 go.mod 进行下载和管理,可以通过 GOPRI ...
- [FE] uni-app Card 卡片组件 uni-card 用法
使用 uni-card 和其它组件没有什么区别,关注支持的属性和事件即可. 对于属性,需要特别注意值的类型,比如不要把非字符串的当做字符串处理. 举例,如下 is-full 需要 Boolean 类型 ...
- [Gin] gin-jwt 业务逻辑中使用实例化的 middleware 的方式
依然需要按文档所示实例化一个 authMiddleware. 在路由组中使用的方式是 authMiddleware.MiddlewareFunc(). 通过追踪 MiddlewareFunc 可以知道 ...
- [Auth] 浅谈 jwt token 的妙处
无状态(易扩展). 有过期时间限制,相对安全(可以有多个有效的 token). 更轻量(适合少量信息),类似传统 query string 签名方式. 标准统一(跨语言). Refer:JWT Aut ...
- 2019-8-31-C#-如何引用-WshShell-类
title author date CreateTime categories C# 如何引用 WshShell 类 lindexi 2019-08-31 16:55:58 +0800 2019-3- ...
- 开发日志:企业微信实现扫码登录(WEB)
一:获取扫码登陆所需的参数:appid,secret,agentid 登录企业微信:https://work.weixin.qq.com/ 扫码登录文档:https://work.weixin.qq. ...
- VSCode 中安装 esp-idf
一.准备工具 首先需要安装好 VSCode 软件和 esp-idf 环境. 安装 VSCode VSCode 安装比较简单,我就不赘述了,进入官网下载一键安装即可 VSCode官网:https://c ...
- 001_Cadence软件的安装与介绍
001_Cadence软件的安装与介绍 软件版本16.6,软件下载:搜索PCB联盟; 安装步骤: 1) 把5个分卷的压缩包解压到同一文件夹; 2) 双击Setup.exe开始安装,先安装Lic ...
- SQL Server实战四:查询数据库的数据
本文介绍基于Microsoft SQL Server软件,实现数据库表中多种数据查询方法的具体操作. 目录 1 指定列或全部列查询--查询S表学生记录 2 指定列或全部列查询--查询学生姓名与出生 ...
- set 容器详解 附大根堆题解
声明 本文中题解部分内容大部分转载自 @sonnety 的这篇博客中,本文为为方便复习而写的结论类文章,读者可自行跳转至原文处阅读. PART 1 set 什么是 set --来源cppreferen ...