一、配置環境準備
1.1 mail.smtp.host查看
打開outlook:文件–》信息–》賬戶設置–》雙擊賬戶
1.2 修改本地hosts文件
最好在C:\Windows\System32\drivers\etc\hosts文件配置一下主機名,
ip可以在命令行中 ping mail.unipower.cn 查看到
hosts文件新增一行:
ip mail.unipower.cn
1.3 pom.xml
pom.xml新增依賴:
<!-- mail -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
二、代碼demo
2.1 outlook會議邀請demo
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;
import javax.activation.DataHandler;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
public class MailOutlook {
Session session; //創建session
static String name = "[email protected]"; //發送用戶郵箱
static String pwd = "xxxxx"; //發送用戶密碼
static String username = "[email protected]"; //接收用戶郵箱
static String title = "主題"; //發送郵件主題
static String text = "郵件正文"; //發送郵件內容
static String startTimew = "2019-05-14 08:00:00";//開始時間
static String endTimew = "2019-05-14 09:00:00"; //結束時間
//需要轉換的時間
static String startTime = getUtc(startTimew);
static String endTime = getUtc(endTimew);
private static Properties emailProp = new Properties();
private static class EmailAuthenticator extends Authenticator {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
String userId = emailProp.getProperty("userId", name);
String password = emailProp.getProperty("password", pwd);
return new PasswordAuthentication(userId, password);
}
}
public static void send() throws Exception {
try {
String fromEmail = emailProp.getProperty("fromEmail", name);
String toEmail=emailProp.getProperty("toEmail", username);
Properties props = new Properties();
try {
//端口一般爲 25/465/487 可以使用telnet host port查看是否可用 比如 telnet mail.unipower.cn 25
props.put("mail.smtp.port", "25");
//配置outlook上查到的host
props.put("mail.smtp.host", "mail.unipower.cn");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.ssl", "true");
} catch (Exception e) {
e.printStackTrace();
}
Session session;
Authenticator authenticator = new EmailAuthenticator();
session = Session.getInstance(props, authenticator);
MimeMessage message = new MimeMessage(session);
//設置發件人
message.setFrom(new InternetAddress(fromEmail));
//設置單個收件人
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
/*
設置多收件人,Message.RecipientType.CC:密送
Message.RecipientType.BCC:抄送
Message.RecipientType.TO:收件人
*/
List<String> emails = new ArrayList<>();
emails.add("[email protected]")
message.addRecipients(Message.RecipientType.TO,setRecipientT0(emails));
message.setSubject(title);
StringBuffer buffer = new StringBuffer();
buffer.append("BEGIN:VCALENDAR\n"
+ "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
+ "VERSION:2.0\n"
+ "METHOD:REQUEST\n" //METHOD:CANCEL 取消會議 METHOD:REQUEST 創建和更新會議
+ "BEGIN:VEVENT\n"
+ "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+fromEmail+"\n"
+ "ORGANIZER:MAILTO:"+fromEmail+"\n"
+ "DTSTART:"+startTime+"\n"
+ "DTEND:"+endTime+"\n"
+ "LOCATION:會議室01\n"
//如果id相同的話,outlook會認爲是同一個會議請求,所以使用uuid。
+ "UID:"+UUID.randomUUID().toString()+"\n"
+ "CATEGORIES:111111111r\n"
+ "DESCRIPTION:"+文本\\n內容+"\n\n" // 會議內容換行爲\\n
+ "SUMMARY:2222222222t\n" + "PRIORITY:5\n"
+ "SEQUENCE:1\n" //設置優先級 其中cancel>update>create
+ "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
+ "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
+ "DESCRIPTION:Reminder\n" + "END:VALARM\n"
+ "END:VEVENT\n" + "END:VCALENDAR");
Multipart multipart = new MimeMultipart();
BodyPart messageBodyPart = new MimeBodyPart();
// 測試下來如果不這麼轉換的話,會以純文本的形式發送過去,
//如果沒有text/calendar;method=REQUEST;charset=\"UTF-8\",outlook會議附件的形式存在,而不是直接打開就是一個會議請求
messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),
"text/calendar;method=REQUEST;charset=\"UTF-8\"")));
// 添加會議邀請內容
multipart.addBodyPart(messageBodyPart);
// 附件功能
// 創建消息部分
BodyPart fujianBodyPart = new MimeBodyPart();
// 添加網絡附件
for (int i = 0; i < documents.size(); i++) {
URL url = new URL(documents.get(i).getUrl());
DataHandler dataHandler = new DataHandler(url);
MimeBodyPart messageBodyPart3 = new MimeBodyPart();
messageBodyPart3.setDataHandler(dataHandler);
messageBodyPart3.setFileName(MimeUtility.encodeText(documents.get(i).getName()));
multipart.addBodyPart(messageBodyPart3);
}
message.setContent(multipart,"text/html;charset=UTF-8");
//message.setText("測試");
Transport.send(message);
} catch (MessagingException me) {
me.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
/*** 設置收件人/抄送人/密送人地址信息*/
private InternetAddress[] setRecipientT0(List<String> recipientT0List) throws MessagingException, UnsupportedEncodingException {
if (recipientT0List.size() > 0) {
InternetAddress[] sendTo = new InternetAddress[recipientT0List.size()];
for (int i = 0; i < recipientT0List.size(); i++) {
System.out.println("發送到:" + recipientT0List.get(i));
sendTo[i] = new InternetAddress(recipientT0List.get(i), "", "UTF-8");
}
return sendTo;
}
return null;
}
//轉utc時間
public static String getUtc(String str){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long millionSeconds = 0;
try {
millionSeconds = sdf.parse(str).getTime();
} catch (ParseException e1) {
e1.printStackTrace();
}//毫秒
Date date = new Date(millionSeconds );
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化日期
String nowTime="";
nowTime= df.format(date);
String utcTime = nowTime.replace("-", "").replace(" ", "T").replace(":", "");//轉換utc時間
return utcTime;
}
//main函數 測試
public static void main(String[] args) {
try {
send();
//cancel();
//update();
System.out.println("success");
} catch (Exception e) {
e.printStackTrace();
}
}
}
修改和創建其實只要UID保持一致然後修改以下內容,
- SEQUENCE:2 設置優先級 cance>update>create
取消會議主要是和修改uuid必須一致,主要是以下兩點不一致:
- SEQUENCE:3 設置優先級 cance>update>create
- “METHOD:REQUEST\n” //METHOD:CANCEL 取消會議 METHOD:REQUEST 創建和更新會議
2.2 取消會議
public static void cancel() throws Exception {
try {
String fromEmail = emailProp.getProperty("fromEmail", name);
String toEmail=emailProp.getProperty("toEmail", username);
Properties props = new Properties();
try {
//端口一般爲 25/465/487 可以使用telnet host port查看是否可用 比如 telnet mail.unipower.cn 25
props.put("mail.smtp.port", "25");
//配置outlook上查到的host
props.put("mail.smtp.host", "mail.unipower.cn");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.ssl", "true");
} catch (Exception e) {
e.printStackTrace();
}
Session session;
Authenticator authenticator = new EmailAuthenticator();
session = Session.getInstance(props, authenticator);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromEmail));
//設置單個收件人
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
/*
設置多收件人,Message.RecipientType.CC:密送
Message.RecipientType.BCC:抄送
Message.RecipientType.TO:收件人
*/
List<String> emails = new ArrayList<>();
emails.add("[email protected]")
message.addRecipients(Message.RecipientType.TO,setRecipientT0(emails));
message.setSubject(title);
StringBuffer buffer = new StringBuffer();
buffer.append("BEGIN:VCALENDAR\n"
+ "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
+ "VERSION:2.0\n"
+ "METHOD:CANCEL \n" //METHOD:CANCEL 取消會議 METHOD:REQUEST 創建和更新會議
+ "BEGIN:VEVENT\n"
+ "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+fromEmail+"\n"
+ "ORGANIZER:MAILTO:"+fromEmail+"\n"
+ "DTSTART:"+startTime+"\n"
+ "DTEND:"+endTime+"\n"
+ "LOCATION:會議室01\n"
//這裏的uuid要和會議邀請的uuid一致,實際生產中可以將uuid存到數據庫中
+ "UID:"+XXX(和會議邀請uuid一致)+"\n"
+ "CATEGORIES:111111111r\n"
+ "DESCRIPTION:"+文本\\n內容+"\n\n" // 會議內容換行爲\\n
+ "SUMMARY:2222222222t\n" + "PRIORITY:5\n"
+ "SEQUENCE:3\n" //設置優先級 其中cancel>update>create
+ "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
+ "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
+ "DESCRIPTION:Reminder\n" + "END:VALARM\n"
+ "END:VEVENT\n" + "END:VCALENDAR");
BodyPart messageBodyPart = new MimeBodyPart();
// 測試下來如果不這麼轉換的話,會以純文本的形式發送過去,
//如果沒有text/calendar;method=REQUEST;charset=\"UTF-8\",outlook會議附件的形式存在,而不是直接打開就是一個會議請求
messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),
"text/calendar;method=REQUEST;charset=\"UTF-8\"")));
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
//message.setText("測試");
Transport.send(message);
} catch (MessagingException me) {
me.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
2.3 會議修改
public static void update() throws Exception {
try {
String fromEmail = emailProp.getProperty("fromEmail", name);
String toEmail=emailProp.getProperty("toEmail", username);
Properties props = new Properties();
try {
//端口一般爲 25/465/487 可以使用telnet host port查看是否可用 比如 telnet mail.unipower.cn 25
props.put("mail.smtp.port", "25");
//配置outlook上查到的host
props.put("mail.smtp.host", "mail.unipower.cn");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.ssl", "true");
} catch (Exception e) {
e.printStackTrace();
}
Session session;
Authenticator authenticator = new EmailAuthenticator();
session = Session.getInstance(props, authenticator);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromEmail));
//設置單個收件人
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
/*
設置多收件人,Message.RecipientType.CC:密送
Message.RecipientType.BCC:抄送
Message.RecipientType.TO:收件人
*/
List<String> emails = new ArrayList<>();
emails.add("[email protected]")
message.addRecipients(Message.RecipientType.TO,setRecipientT0(emails));
message.setSubject(title);
StringBuffer buffer = new StringBuffer();
buffer.append("BEGIN:VCALENDAR\n"
+ "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
+ "VERSION:2.0\n"
+ "METHOD:REQUEST\n" //METHOD:CANCEL 取消會議 METHOD:REQUEST 創建和更新會議
+ "BEGIN:VEVENT\n"
+ "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+fromEmail+"\n"
+ "ORGANIZER:MAILTO:"+fromEmail+"\n"
+ "DTSTART:"+startTime+"\n"
+ "DTEND:"+endTime+"\n"
+ "LOCATION:會議室01\n"
//這裏的uuid要和會議邀請的uuid一致,實際生產中可以將uuid存到數據庫中
+ "UID:"+XXX(和會議邀請uuid一致)+"\n"
+ "CATEGORIES:111111111r\n"
+ "DESCRIPTION:"+文本\\n內容+"\n\n" // 會議內容換行爲\\n
+ "SUMMARY:2222222222t\n" + "PRIORITY:5\n"
+ "SEQUENCE:2\n" //設置優先級 其中cancel>update>create
+ "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
+ "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
+ "DESCRIPTION:Reminder\n" + "END:VALARM\n"
+ "END:VEVENT\n" + "END:VCALENDAR");
BodyPart messageBodyPart = new MimeBodyPart();
// 測試下來如果不這麼轉換的話,會以純文本的形式發送過去,
//如果沒有text/calendar;method=REQUEST;charset=\"UTF-8\",outlook會議附件的形式存在,而不是直接打開就是一個會議請求
messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),
"text/calendar;method=REQUEST;charset=\"UTF-8\"")));
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);
//message.setText("測試");
Transport.send(message);
} catch (MessagingException me) {
me.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
三、發送普通郵件
3.1 普通郵件工具類
/**
* @Author hld
* @Description 發送普通郵件
* @Date 16:18 2019/6/18
* @Param userList:收件人列表
* ccUserList:抄送人列表
* content:內容
* topic:標題
* @return
**/
public void normalEmail(List<String> userList,List<String> ccUserList,String content,String topic){
try {
String fromEmail = emailProp.getProperty("fromEmail", username);
Properties props = new Properties();
try {
props.put("mail.smtp.port", port);
props.put("mail.smtp.host", host);
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.ssl", "true");
} catch (Exception e) {
e.printStackTrace();
}
Session session;
Authenticator authenticator = new EmailAuthenticator();
session = Session.getInstance(props, authenticator);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(fromEmail)); //發件人
//設置多發件人 BCC:抄送 CC:密送 TO:收件人
if (userList != null && userList.size() > 0){
message.addRecipients(Message.RecipientType.TO,setRecipientT0(userList));
}
//設置單個發件人
//message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
//設置抄送地址 BCC:抄送 CC:密送 TO:收件人
if (ccUserList != null && ccUserList.size() > 0){
message.addRecipients(Message.RecipientType.BCC,setRecipientT0(ccUserList));
}
message.setSubject(topic); //設置會議主題
// 添加網絡附件
Multipart multipart = new MimeMultipart();
// 創建消息部分
BodyPart messageBodyPart = new MimeBodyPart();
// 消息
messageBodyPart.setText(content);
multipart.addBodyPart(messageBodyPart);
// 循環網絡附件,獲取url 附件名稱等
for (int i = 0; i < documents.size(); i++) {
URL url = new URL(documents.get(i).getUrl());
DataHandler dataHandler = new DataHandler(url);
MimeBodyPart messageBodyPart3 = new MimeBodyPart();
messageBodyPart3.setDataHandler(dataHandler);
messageBodyPart3.setFileName(MimeUtility.encodeText(documents.get(i).getName()));
multipart.addBodyPart(messageBodyPart3);
}
// 發送完整消息
message.setContent(multipart);
// message.setText(content);
Transport.send(message);
} catch (MessagingException me) {
me.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}