1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
package com.ruoyi.common.email.util;
import cn.hutool.extra.mail.Mail;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.email.EmailConfig;
import com.ruoyi.common.email.EmailVO;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.exception.tool.EmailConfigException;
import com.ruoyi.common.exception.tool.EmailSendException;
import com.ruoyi.common.utils.EncryptUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.sun.mail.util.MailSSLSocketFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.activation.DataSource;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.GeneralSecurityException;
import java.util.*;
public class EmailSendUtil {
private static final Logger log = LoggerFactory.getLogger(EmailSendUtil.class);
private static final String EMAIL_CONFIG_HOST = "email.config.host";
private static final String EMAIL_CONFIG_PORT = "email.config.port";
private static final String EMAIL_CONFIG_USER = "email.config.user";
private static final String EMAIL_CONFIG_PASS = "email.config.pass";
private static final String EMAIL_CONFIG_FROM_USER = "email.config.fromUser";
/**
* 获取邮件配置信息
* @return
*/
public static EmailConfig getEmailConfig(){
EmailConfig emailConfig = new EmailConfig();
emailConfig.setHost(getCacheValue(EMAIL_CONFIG_HOST));
emailConfig.setPort(getCacheValue(EMAIL_CONFIG_PORT));
emailConfig.setUser(getCacheValue(EMAIL_CONFIG_USER));
emailConfig.setPass(getCacheValue(EMAIL_CONFIG_PASS));
emailConfig.setFromUser(getCacheValue(EMAIL_CONFIG_FROM_USER));
return emailConfig;
}
/**
* 获取邮件账户信息
* @return
*/
public static MailAccount getMailAccount()
{
EmailConfig emailConfig = getEmailConfig();
// 封装
MailAccount account = new MailAccount();
// 设置用户
String user = emailConfig.getFromUser().split("@")[0];
account.setHost(emailConfig.getHost());
account.setPort(Integer.parseInt(emailConfig.getPort()));
account.setAuth(true);
account.setPass(emailConfig.getPass());
//方案一:
// SSL 握手失败可能与协议版本协商不稳定有关,需在代码中强制指定 TLSv1.2:
account.setSslProtocols("TLSv1.2");
// 方案二:
// 补充 SSL SocketFactory 相关参数,避免因缺少证书信任导致握手失败:添加 SSL 安全套接字工厂配置
// MailSSLSocketFactory sf = null;
// try {
// sf = new MailSSLSocketFactory();
// sf.setTrustAllHosts(true); // 信任所有主机(测试环境可临时启用):ml-citation{ref="4" data="citationList"}
// account.setCustomProperty("mail.smtp.ssl.socketFactory", sf);
// account.setCustomProperty("mail.smtp.ssl.enable", "true");
// } catch (GeneralSecurityException e) {
// throw new RuntimeException(e);
// }
// ssl方式发送
account.setSslEnable(true);
// 使用STARTTLS安全连接
account.setStarttlsEnable(true);
account.setUser(emailConfig.getUser());
account.setFrom(emailConfig.getFromUser());
return account;
}
/**
* 单个收件人
* 发送邮件 ,不包含照片主体
* @param to
* @param subject
* @param content
* @param isHtml
* @param files
*/
public static void send(String to, String subject, String content, boolean isHtml, File... files){
MailAccount account = getMailAccount();
String send = MailUtil.send(account, to, subject, content, isHtml, files);
log.info(String.format("邮件发送返回结果:%s",send));
}
/**
* 多个收件人
* @param tos
* @param subject
* @param content
* @param isHtml
* @param files
*/
public static void sendTos(Collection<String> tos, String subject, String content, boolean isHtml, File... files){
MailAccount account = getMailAccount();
String send = MailUtil.send(account, tos, subject, content, isHtml, files);
log.info(String.format("邮件发送返回结果:%s",send));
}
/**
* 发送邮件, 可发送图片
* @param to
* @param subject
* @param content
* @param imageStrMap
* @param isHtml
* @param files
*/
public static void send(String to, String subject, String content, Map<String,String> imageStrMap, boolean isHtml, File... files){
MailAccount account = getMailAccount();
Map<String, InputStream> imageMap = new HashMap<>();
Set<String> imagesKeys = imageStrMap.keySet();
for (String imagesKey : imagesKeys) {
String imageurl = imageStrMap.get(imagesKey);
try {
if(StringUtils.isNotEmpty(imageurl)){
URL url = new URL(imageurl);
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
// 从 inputStream 中读取文件流并进行处理
imageMap.put(imagesKey,inputStream);
}
} catch (Exception e) {
log.info(String.format("图片Url获取数据,出错的是:%s:%s",imagesKey,imageurl));
e.printStackTrace();
}
}
String send = MailUtil.send(account, to, subject, content, imageMap, isHtml, files);
log.info(String.format("邮件发送返回结果:%s",send));
}
/**
* 发送多人, 可发送图片
* @param tos
* @param subject
* @param content
* @param imageStrMap
* @param isHtml
* @param files
*/
public static void sendTos(Collection<String> tos, String subject, String content, Map<String,String> imageStrMap, boolean isHtml, File... files){
MailAccount account = getMailAccount();
Map<String, InputStream> imageMap = new HashMap<>();
Set<String> imagesKeys = imageStrMap.keySet();
for (String imagesKey : imagesKeys) {
String imageurl = imageStrMap.get(imagesKey);
try {
if(StringUtils.isNotEmpty(imageurl)){
URL url = new URL(imageurl);
URLConnection conn = url.openConnection();
InputStream inputStream = conn.getInputStream();
// 从 inputStream 中读取文件流并进行处理
imageMap.put(imagesKey,inputStream);
}
} catch (Exception e) {
log.info(String.format("图片Url获取数据,出错的是:%s:%s",imagesKey,imageurl));
e.printStackTrace();
}
}
String send = MailUtil.send(account, tos, subject, content, imageMap, isHtml, files);
log.info(String.format("邮件发送返回结果:%s",send));
}
/**
* 发送邮件
* @param emailVo
* @param emailConfig
*/
public static void send(EmailVO emailVo, EmailConfig emailConfig) {
if (emailConfig == null) {
emailConfig = getEmailConfig();
}
if (emailConfig == null) {
throw new EmailConfigException("Email参数设置为空,请检查参数设置");
}
MailAccount account = getMailAccount();
String content = emailVo.getContent();
// 发送
try {
int size = emailVo.getTos().size();
Mail mail = Mail.create(account);
mail.setTos(emailVo.getTos().toArray(new String[size]))
.setTitle(emailVo.getSubject())
.setContent(content)
.setHtml(true);
List<DataSource> attachments = emailVo.getAttachments();
if (attachments != null && attachments.size() > 0) {
mail.setAttachments(attachments.toArray(new DataSource[]{}));
}
List<File> files = emailVo.getFiles();
if (files != null && files.size() > 0) {
mail.setFiles(files.toArray(new File[]{}));
}
mail
//关闭session
.setUseGlobalSession(false)
.send();
} catch (Exception e) {
throw new EmailSendException(e.getMessage());
}
}
/**
* 设置cache key
*
* @param configKey 参数键
* @return 缓存键key
*/
private static String getCacheKey(String configKey)
{
return CacheConstants.SYS_CONFIG_KEY + configKey;
}
/**
* 获取缓存值
* @param configKey
* @return
*/
private static String getCacheValue(String configKey){
if(!configKey.startsWith(CacheConstants.SYS_CONFIG_KEY)){
configKey = getCacheKey(configKey);
}
String value = SpringUtils.getBean(RedisCache.class).getCacheObject(configKey);
if(StringUtils.isEmpty(value)){
throw new EmailConfigException(String.format("未找到email相关参数,请检查%s参数设置并同步到redis缓存。",configKey));
}
return value;
}
}
|