1.廢話不多說,需要準備一些必要的引數,這里以QQ郵箱為例
首先要獲取郵箱對應的16位授權碼,這是為了使用郵箱服務器,進入QQ郵箱,在設定 -> 賬戶里面找到下面的服務開關,打開任意一個,smtp表示發送

2.利用maven的pom檔案匯入需要的sdk包
<!--郵箱-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.5</version>
</dependency>
3.然后下面的我這里封裝好的完整發送郵箱工具類,支持富文本,圖片,各種附件,具體的操作看main方法和注解就不詳解了
import com.sun.mail.util.MailSSLSocketFactory;
import jodd.util.URLDecoder;
import org.springframework.web.multipart.MultipartFile;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.util.*;
/*
郵箱工具類
*/
public class MailUtils {
//郵箱服務器(可以理解為中轉站),常見的如網網易的郵箱服務器 smtp.163.com ,QQ的是smtp.qq.com
//第一個值是協議,第二個值是哪個公司提供的郵箱
private static final String SERVER_URL[] = {"smtp.qq.com"};
//協議型別,常用協議有三種 smtp imap pop3,其中imap pop3是表示接收,smtp是發送
private static final String PROTOCOL_TYPE[] = {"smtp", "imap", "pop3"};
//是否開啟授權
private static final String AUTHOEIZATION = "true";
//是否開啟SSL加密
private static final String SSL = "true";
//發送郵件的郵箱賬號,可修改
public static String MAIL_ACCOUNT = "xxxxx@qq.com";
//郵箱賬號對應的協議16位授權碼,可修改,必須和發郵件的賬戶一致
public static String MAIL_AUTHOEIZATION_CODE = "aaaaaaa";
//郵件文本類容格式(text/html是由游覽器自己決議,可以決議富文本,text/plain是表示直接就是純文字,不需要決議)
private static final String[] TABLE = {"TEXT/HTML;charset=UTF-8", "TEXT/PLAIN;charset=UTF-8"};
//全域主體參考
private static MimeMultipart mimeMultipart;
//訊息體全域參考
private static MimeBodyPart mimeBodyPart;
public static void main(String[] args) {
List<String> strings=new ArrayList<>();
strings.add("a");
List list=strings;
list.forEach(data -> System.out.println(data));
//根據路徑拿附件
String[] stringUrls = {"D:\\a.txt", "D:\\b.xlsx"};
//根據檔案流物體拿附件
File[] files = {new File("D:\\c.jpg")};
//呼叫郵件發送方法
System.out.println(getMail(MAIL_ACCOUNT, "測驗", "胖!</br><img src='D:\\c.jpg'/></br>", stringUrls, files));
}
/**
* 發送郵寄
*
* @param receiveMail 收件人郵箱賬號
* @param title 郵件標題
* @param content 郵件內容,TEXT/HTML格式下可以是富文本
* @param objects 附件,陣列型別引數,String[]陣串列示路徑傳附件,File[]表示file實體傳附件,MultipartFile[]表示multipartFile實體傳附件
* @return
*/
public static synchronized boolean getMail(String receiveMail, String title, String content, Object[]... objects) {
try {
//1.創建一個組態檔并保存,設定協議服務器地址,協議型別,是否授權
Properties properties = new Properties();
properties.setProperty("mail.host", SERVER_URL[0]);
properties.setProperty("mail.transport.protocol", PROTOCOL_TYPE[0]);
properties.setProperty("mail.smtp.auth", AUTHOEIZATION);
//2.QQ存在一個特性設定SSL加密
MailSSLSocketFactory ssl = new MailSSLSocketFactory();
ssl.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", SSL);
properties.put("mail.smtp.ssl.socketFactory", ssl);
//3.創建一個郵箱的session物件,要放入發送郵件的郵箱賬號和協議授權嘛
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(MAIL_ACCOUNT, MAIL_AUTHOEIZATION_CODE);
}
});
//4.開啟debug模式,就是開啟每一步的操作列印
session.setDebug(true);
//5.獲取連接物件
Transport transport = session.getTransport();
//6.連接郵箱對應服務器,發送是 smtp 協議服務器
transport.connect(SERVER_URL[0], MAIL_ACCOUNT, MAIL_AUTHOEIZATION_CODE);
//7.創建郵件物件
MimeMessage mimeMessage = new MimeMessage(session);
//8.郵件發送人賬號
mimeMessage.setFrom(new InternetAddress(MAIL_ACCOUNT));
//9.郵件接收人賬號
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(receiveMail));
//10.郵件標題
mimeMessage.setSubject(title);
//11.構建郵件主體
mimeMessage.setContent(addMimeMultipart(content, objects));
//12.發送郵件
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
//13.關閉連接
transport.close();
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
return true;
}
/**
* 構建郵件主體(包括內容,附件(一切檔案),富文本等)
*
* @param content 文本內容,在TEXT/HTML格式下可以是富文本
* @param objects 附件,富文本圖片
* @return
* @throws MessagingException
*/
private static synchronized MimeMultipart addMimeMultipart(String content, Object[] objects) throws MessagingException {
//得到主體實體
mimeMultipart = new MimeMultipart();
//處理富文本圖片標簽等類容,根據img標簽分組,然后回圈處理
String[] contentImgs = content.split("<img");
StringBuilder stringBuilder = new StringBuilder("");
for (String img : contentImgs) {
//判斷當前內容里面是否有img的src屬性
if (img.indexOf(" src='") != -1) {
//把img拼接回去
img = "<img" + img;
//判斷是否有以下幾種格式
int index = 0;
Map<String, Integer> map = new HashMap<>();
map.put("jpg", img.indexOf(".jpg'/>"));
map.put("png", img.indexOf(".png'/>"));
map.put("pdf", img.indexOf(".pdf'/>"));
map.put("jpeg", img.indexOf(".jpeg'/>"));
for (String s : map.keySet()) {
int size = map.get(s);
if (size != -1) {
index = s.equals("jpeg") ? size + 8 : size + 7;
}
}
//如果找到了對應的格式圖片或者表情,則生成一個新的名稱,替換掉原來的路徑
if (index != 0) {
//新名稱,這是用來給郵箱尋找圖片的別名
String name = String.valueOf(new Date().getTime());
//原來的路徑
String url = img.substring(10, index - 3);
//新名稱替換原來的路徑
img = img.substring(0, 10) + "cid:" + name + img.substring(index, img.length());
//生成富文本對應的圖片或者表情的訊息體
mimeMultipart.addBodyPart(addRichUrl(url, name));
}
}
stringBuilder.append(img);
}
//把最終的文本內容放入訊息體回傳結果給主體
mimeMultipart.addBodyPart(addContent(stringBuilder.toString()));
//判斷是否帶了附件路徑,附件檔案流物體,富文本這些東西
if (objects.length > 0) {
for (Object object : objects) {
//判斷是否是附件路徑陣列,是則回圈放入附件訊息體
if (object instanceof String[]) {
String[] stringUrls = (String[]) object;
for (String s : stringUrls) {
mimeMultipart.addBodyPart(addAccessoryUrl(s));
}
}
//判斷是否是附件檔案流File陣列,是則回圈放入附件訊息體
if (object instanceof File[]) {
File[] files = (File[]) object;
for (File file : files) {
mimeMultipart.addBodyPart(addAccessoryFile(file));
}
}
//判斷是否帶了附件檔案流MultipartFile陣列,是則回圈放入附件訊息體
if (object instanceof MultipartFile[]) {
MultipartFile[] multipartFiles = (MultipartFile[]) object;
for (MultipartFile multipartFile : multipartFiles) {
mimeMultipart.addBodyPart(addAccessoryMultipartFile(multipartFile));
}
}
}
}
return mimeMultipart;
}
/**
* 構建純文本訊息體
*
* @param content 文本內容
* @return
*/
private static synchronized MimeBodyPart addContent(String content) {
try {
if (StringUtils.getNotNull(content)) {
return null;
}
mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(content, TABLE[0]);
return mimeBodyPart;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 利用附件路徑構建附件訊息體
*
* @param fileUrl 附件路徑
* @return
*/
private static synchronized MimeBodyPart addAccessoryUrl(String fileUrl) {
try {
mimeBodyPart = new MimeBodyPart();
//使用io讀取檔案流
File file = new File(fileUrl);
//把檔案流放入訊息體
mimeBodyPart.attachFile(file);
//解決中文亂碼問題,放入當前檔案名
mimeBodyPart.setFileName(MimeUtility.encodeText(file.getName()));
return mimeBodyPart;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 利用附件檔案流File物體構建附件訊息體
*
* @param file 附件檔案流物體
* @return
*/
private static synchronized MimeBodyPart addAccessoryFile(File file) {
try {
mimeBodyPart = new MimeBodyPart();
//把檔案流放入訊息體
mimeBodyPart.attachFile(file);
//解決中文亂碼問題,放入當前檔案名
mimeBodyPart.setFileName(MimeUtility.encodeText(file.getName()));
return mimeBodyPart;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 利用附件檔案流MultipartFile物體構建附件訊息體
*
* @param multipartFile 附件檔案流物體
* @return
*/
private static synchronized MimeBodyPart addAccessoryMultipartFile(MultipartFile multipartFile) {
try {
if (multipartFile != null) {
mimeBodyPart = new MimeBodyPart();
//拿到檔案流
ByteArrayDataSource byteArrayDataSource = new ByteArrayDataSource(multipartFile.getInputStream(), multipartFile.getContentType());
//拿到檔案名
byteArrayDataSource.setName(multipartFile.getOriginalFilename());
//把檔案流放入訊息體
mimeBodyPart.setDataHandler(new DataHandler(byteArrayDataSource));
//這里檔案源名稱由客戶端上傳 一般都是經過url編碼的 我們先解碼 再轉成郵箱的編碼
mimeBodyPart.setFileName(MimeUtility.encodeText(URLDecoder.decode(multipartFile.getOriginalFilename(), "utf-8")));
return mimeBodyPart;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 利用富文本圖片或表情的路徑構建富文本訊息體
*
* @param fileUrl 富文本圖片或表情路徑
* @param name 富文本圖片或表情別名,對應<img> 標簽里面的src屬性值
* @return
*/
private static synchronized MimeBodyPart addRichUrl(String fileUrl, String name) {
try {
mimeBodyPart = new MimeBodyPart();
//使用io讀取檔案流
File file = new File(fileUrl);
//把檔案流放入訊息體
mimeBodyPart.attachFile(file);
//指定這個檔案為富文本圖片或表情
mimeBodyPart.setDescription(MimeBodyPart.INLINE);
//對應<img> 標簽里面的src值
mimeBodyPart.setContentID("<" + name + ">");
//解決中文亂碼問題,放入當前檔案名
mimeBodyPart.setFileName(MimeUtility.encodeText(file.getName()));
return mimeBodyPart;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
如果喜歡就收藏,點贊,評論吧
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/256362.html
標籤:java
上一篇:Java基礎知識難點總結
下一篇:資料結構-快速排序
