1 import java.io.FileOutputStream;
2 import java.io.IOException;
3 import java.io.OutputStream;
4 import java.io.UnsupportedEncodingException;
5 import java.util.Calendar;
6 import java.util.Date;
7 import java.util.HashSet;
8 import java.util.Properties;
9 import java.util.Set;
10 import java.util.regex.Matcher;
11 import java.util.regex.Pattern;
12 import javax.mail.MessagingException;
13 import javax.mail.Session;
14 import javax.mail.Transport;
15 import javax.mail.internet.InternetAddress;
16 import javax.mail.internet.MimeMessage;
17
18 import com.yanfuchang.work.utils.fileIo.FileUtils;
19
20 public class MailSendUtil {
21 /**
22 * 验证邮箱
23 */
24 public static boolean checkEmail(String email) {
25 boolean flag = false;
26 try {
27 String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
28 Pattern regex = Pattern.compile(check);
29 Matcher matcher = regex.matcher(email);
30 flag = matcher.matches();
31 } catch (Exception e) {
32 flag = false;
33 }
34 return flag;
35 }
36
37 /**
38 * 验证手机号码,11位数字,1开通,第二位数必须是3456789这些数字之一 *
39 */
40 public static boolean checkMobileNumber(String mobileNumber) {
41 boolean flag = false;
42 try {
43 Pattern regex = Pattern.compile("^1[345789]\\d{9}$");
44 Matcher matcher = regex.matcher(mobileNumber);
45 flag = matcher.matches();
46 } catch (Exception e) {
47 e.printStackTrace();
48 flag = false;
49 }
50 return flag;
51 }
52
53 private String fromAddr; // 发件人邮箱
54 private String password; // 发件人密码
55 private String smtpHost; // smtp 主机地址
56 private boolean bAuthorOpen = true; // 是否授权验证
57 private boolean bSSLOpen = false; // 是否开启SSL
58 private String smtpPort = "25"; // smtp端口 默认 25 SSL 465或587
59 private Set<String> recToList = null; // 收件人列表
60 private Set<String> recCCList = null; // 抄送人列表
61 private Set<String> recBCCList = null; // 密送人列表
62 private String subjectText = "test"; // 邮件主题
63 private String context = "test"; // 发送内容
64 private boolean bSaveEml = false; // 是否保存邮件.eml
65 private String charset = "UTF-8"; // 发送字符编码 UTF-8 GB2312
66
67 private String timeOut = "250000";
68 private String savePath = "c:\\email\\";
69
70 public MailSendUtil() {
71 }
72
73 public String getCharset() {
74 return charset;
75 }
76
77 public String getContext() {
78 return context;
79 }
80
81 public String getFromAddr() {
82 return fromAddr;
83 }
84
85 public String getPassword() {
86 return password;
87 }
88
89 public Set<String> getRecBCCList() {
90 return recBCCList;
91 }
92
93 public Set<String> getRecCCList() {
94 return recCCList;
95 }
96
97 public Set<String> getRecToList() {
98 return recToList;
99 }
100
101 public String getSavePath() {
102 return savePath;
103 }
104
105 public String getSmtpHost() {
106 return smtpHost;
107 }
108
109 public String getSmtpPort() {
110 return smtpPort;
111 }
112
113 public String getSubjectText() {
114 return subjectText;
115 }
116
117 public String getTimeOut() {
118 return timeOut;
119 }
120
121 public boolean isbAuthorOpen() {
122 return bAuthorOpen;
123 }
124
125 public boolean isbSaveEml() {
126 return bSaveEml;
127 }
128
129 public boolean isbSSLOpen() {
130 return bSSLOpen;
131 }
132
133 public boolean SendEmail() {
134 if (fromAddr == null || password == null || subjectText == null || context == null) {
135 return false;
136 }
137 boolean validEmail = checkEmail(fromAddr);
138 if (!validEmail) {
139 return false;
140 }
141 int nSize = 0;
142 for (String string : recToList) {
143 boolean checkEmail1 = checkEmail(string);
144 if (checkEmail1) {
145 nSize++;
146 }
147 }
148 if (nSize == 0) {
149 return false;
150 }
151 Properties props = new Properties(); // 参数配置
152 props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
153 props.setProperty("mail.smtp.host", smtpHost); // 发件人的邮箱的 SMTP 服务器地址
154 props.setProperty("mail.smtp.port", smtpPort);
155 props.setProperty("mail.smtp.timeout", timeOut);
156 if (bAuthorOpen) {
157 props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
158 } else {
159 props.setProperty("mail.smtp.auth", "false"); // 需要请求认证
160 }
161 if (bSSLOpen) {
162 /*
163 * PS: 某些邮箱服务器要求 SMTP 连接需要使用 SSL 安全认证 (为了提高安全性, 邮箱支持SSL连接, 也可以自己开启),
164 * 如果无法连接邮件服务器, 仔细查看控制台打印的 log, 如果有有类似 “连接失败, 要求 SSL 安全连接” 等错误, 开启 SSL 安全连接。
165 * SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接, 需要改为对应邮箱的 SMTP 服务器的端口,
166 * 具体可查看对应邮箱服务的帮助, QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看
167 */
168 props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
169 props.setProperty("mail.smtp.socketFactory.fallback", "false");
170 props.setProperty("mail.smtp.socketFactory.port", smtpPort);
171 }
172
173 // 2. 根据配置创建会话对象, 用于和邮件服务器交互
174 Session session = Session.getInstance(props);
175 session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log
176
177 // 3. 创建一封邮件
178 MimeMessage message = new MimeMessage(session); // 创建邮件对象
179 // 3.1. From: 发件人
180 // 其中 InternetAddress 的三个参数分别为: 邮箱, 显示的昵称(只用于显示, 没有特别的要求), 昵称的字符集编码
181 // 真正要发送时, 邮箱必须是真实有效的邮箱。
182 boolean checkEmail = checkEmail(fromAddr);
183 if (checkEmail) {
184 String showName = StringUtils.substringBefore(fromAddr, "@");
185 try {
186 message.setFrom(new InternetAddress(fromAddr, showName, charset));
187 } catch (UnsupportedEncodingException | MessagingException e) {
188 e.printStackTrace();
189 }
190 } else {
191 return false;
192 }
193 // 3.2. To: 收件人
194 int nRecTo = 0;
195 for (String recTo : recToList) {
196 boolean checkEmail1 = checkEmail(recTo);
197 if (checkEmail1) {
198 String showName = StringUtils.substringBefore(recTo, "@");
199 try {
200 if (nRecTo == 0) {
201 nRecTo++;
202 message.setRecipient(MimeMessage.RecipientType.TO,
203 new InternetAddress(recTo, showName, charset));
204 } else {
205 message.addRecipient(MimeMessage.RecipientType.TO,
206 new InternetAddress(recTo, showName, charset));
207 }
208
209 } catch (UnsupportedEncodingException | MessagingException e) {
210 e.printStackTrace();
211 }
212 }
213 }
214 // 3.3 Cc: 抄送(可选)
215 int nRecCC = 0;
216 for (String recCC : recCCList) {
217 boolean checkEmail1 = checkEmail(recCC);
218 if (checkEmail1) {
219 String showName = StringUtils.substringBefore(recCC, "@");
220 try {
221 if (nRecCC == 0) {
222 message.setRecipient(MimeMessage.RecipientType.CC,
223 new InternetAddress(recCC, showName, charset));
224 } else {
225 message.addRecipient(MimeMessage.RecipientType.CC,
226 new InternetAddress(recCC, showName, charset));
227 }
228
229 } catch (UnsupportedEncodingException | MessagingException e) {
230 e.printStackTrace();
231 }
232 }
233 }
234 // 3.5 Bcc: 密送(可选)
235 int nRecBcc = 0;
236 for (String recBCC : recBCCList) {
237 boolean checkEmail1 = checkEmail(recBCC);
238 if (checkEmail1) {
239 String showName = StringUtils.substringBefore(recBCC, "@");
240 try {
241 if (nRecBcc == 0) {
242 message.setRecipient(MimeMessage.RecipientType.BCC,
243 new InternetAddress(recBCC, showName, charset));
244 } else {
245 message.addRecipient(MimeMessage.RecipientType.BCC,
246 new InternetAddress(recBCC, showName, charset));
247 }
248 } catch (UnsupportedEncodingException | MessagingException e) {
249 e.printStackTrace();
250 }
251 }
252 }
253
254 try {
255 // 3.6. Subject: 邮件主题
256 message.setSubject(subjectText, charset);
257 // 3.7. Content: 邮件正文(可以使用html标签)
258 message.setContent(context, "text/html;charset=" + charset);
259 // 3.8. 设置显示的发件时间
260 message.setSentDate(new Date());
261 // 3.9. 保存前面的设置
262 message.saveChanges();
263 } catch (MessagingException e) {
264 e.printStackTrace();
265 return false;
266 }
267
268 // 3.10. 将该邮件保存到本地
269 if (bSaveEml) {
270 try {
271 if (savePath == null) {
272 savePath = "c:\\smartEmail\\";
273 }
274 Calendar calendar = Calendar.getInstance();
275 long timeInMillis = calendar.getTimeInMillis();
276 FileUtils.createDirectory(savePath);
277 OutputStream out = new FileOutputStream(savePath + timeInMillis + ".eml");
278 message.writeTo(out);
279 out.flush();
280 out.close();
281 } catch (IOException | MessagingException e) {
282 e.printStackTrace();
283 }
284 }
285 try {
286 // 4. 根据 Session 获取邮件传输对象
287 Transport transport = session.getTransport();
288 // 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
289 // PS_01: 成败的判断关键在此一句, 如果连接服务器失败, 都会在控制台输出相应失败原因的 log,
290 // 仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接, 根据给出的错误
291 // 类型到对应邮件服务器的帮助网站上查看具体失败原因。
292 // PS_02: 连接失败的原因通常为以下几点, 仔细检查代码:
293 // (1) 邮箱没有开启 SMTP 服务;
294 // (2) 邮箱密码错误, 例如某些邮箱开启了独立密码;
295 // (3) 邮箱服务器要求必须要使用 SSL 安全连接;
296 // (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务;
297 // (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。
298 transport.connect(fromAddr, password);
299 // (6). 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人,
300 transport.sendMessage(message, message.getAllRecipients());
301 // (7). 关闭连接
302 transport.close();
303 return true;
304 } catch (MessagingException e) {
305 e.printStackTrace();
306 return false;
307 }
308 }
309
310 public void setbAuthorOpen(boolean bAuthorOpen) {
311 this.bAuthorOpen = bAuthorOpen;
312 }
313
314 public void setbSaveEml(boolean bSaveEml) {
315 this.bSaveEml = bSaveEml;
316 }
317
318 public void setbSSLOpen(boolean bSSLOpen) {
319 this.bSSLOpen = bSSLOpen;
320 }
321
322 public void setCharset(String charset) {
323 this.charset = charset;
324 }
325
326 public void setContext(String context) {
327 this.context = context;
328 }
329
330 public void setFromAddr(String fromAddr) {
331 this.fromAddr = fromAddr;
332 }
333
334 public void setPassword(String password) {
335 this.password = password;
336 }
337
338 public void setRecBCCList(Set<String> recBCCList) {
339 this.recBCCList = recBCCList;
340 }
341
342 public void setRecCCList(Set<String> recCCList) {
343 this.recCCList = recCCList;
344 }
345
346 public void setRecToList(Set<String> recToList) {
347 this.recToList = recToList;
348 }
349
350 public void setSavePath(String savePath) {
351 this.savePath = savePath;
352 }
353
354 public void setSmtpHost(String smtpHost) {
355 this.smtpHost = smtpHost;
356 }
357
358 public void setSmtpPort(String smtpPort) {
359 this.smtpPort = smtpPort;
360 }
361
362 public void setSubjectText(String subjectText) {
363 this.subjectText = subjectText;
364 }
365
366 public void setTimeOut(String timeOut) {
367 this.timeOut = timeOut;
368 }
369
370 public static void main(String[] args) {
371 MailSendUtil emailUtil = new MailSendUtil();
372 emailUtil.setFromAddr("");
373 emailUtil.setPassword("");
374 emailUtil.setbAuthorOpen(true);
375 emailUtil.setbSaveEml(true);
376 emailUtil.setbSSLOpen(true);
377 emailUtil.setCharset("UTF-8");
378 emailUtil.setContext("this is a test!");
379 emailUtil.setSmtpHost("smtp.ym.163.com");
380 emailUtil.setSmtpPort("465");
381 emailUtil.setSubjectText("test");
382 Set<String> recToList = new HashSet<String>();
383 recToList.add("XXXXXXX@163.com");
384 emailUtil.setRecToList(recToList);
385 Set<String> recCCList = new HashSet<String>();
386 recCCList.add("XXXXXXX@163.com");
387 emailUtil.setRecCCList(recCCList);
388 Set<String> recBCCList = new HashSet<String>();
389 recBCCList.add("XXXXXXX@163.com");
390 emailUtil.setRecBCCList(recBCCList);
391 boolean sendEmail = emailUtil.SendEmail();
392 System.out.println(sendEmail);
393 }
394 }
依赖:
1 <!-- mail -->
2 <dependency>
3 <groupId>javax.mail</groupId>
4 <artifactId>mail</artifactId>
5 <version>1.4</version>
6 </dependency>