郵件收發
-
電子郵件
要在網絡上實現郵件功能,必須要有專門的郵件服務器。
這些郵件服務器類似於現實生活中的郵局,它主要負責接收用戶投遞過來的郵件,並把郵件投遞到郵件接收者的電子郵箱中。 -
SMTP服務器地址:一般是 smtp.xxx.com,比如163郵箱是smtp.163.com,qq郵箱是smtp.qq.com。
-
電子郵箱(E-Mail地址)的獲得需要在郵件服務器上進行申請。比如我們要使用QQ郵箱,就需要開通郵箱功能;
傳輸協議
-
SMTP協議
發送郵件:
我們通常把處理用戶smtp請求(郵件發送請求)的服務器稱之爲SMTP服務器(郵件發送服務器)。 -
POP3協議
接收郵件:
我們通常把處理用戶pop3請求(郵件接收請求)的服務器稱之爲POP3服務器(郵件接收服務器)。
郵件收發原理
- 大狂神通過smtp協議連接到Smtp服務器,然後發送一封郵件給網易的郵件服務器
- 網易分析發現需要去QQ的郵件服務器,通過smtp協議將郵件轉投給QQ的Smtp服務器
- QQ將接收到的郵件存儲在 [email protected]這個郵件賬號的空間中
- 小狂神通過Pop3協議連接到Pop3服務器收取郵件
- 從 [email protected]這個郵件賬號的空間中取出郵件
- Pop3服務器將取出來的郵件送到小狂神手中
注意有可能你收件人地址,發件人地址等信息都正確了,控制檯也打印了正確的信息,但是在收件箱就是收不到信息。這是因爲可能收件箱服務器拒收了你發的郵件(比如認爲你的郵件是廣告),這時候可能在垃圾箱裏能找到,可能找不到。解決辦法是重複的郵件內容不要多次發送,或者更換收件箱試試
Java發送郵件
-
概述
我們將用代碼完成郵件的發送。這在實際項目中應用的非常廣泛,比如註冊需要發送郵件進行賬號激活,再比如OA項目中利用郵件進行任務提醒等等。 -
使用Java發送 E-mail 十分簡單,但是首先你應該準備 JavaMail API 和Java Activation Framework 。
得到兩個jar包:
1.mail.jar
2.activation.jar -
JavaMail 是sun公司(現以被甲骨文收購)爲方便Java開發人員在應用程序中實現郵件發送和接收功能而提供的一套標準開發包,它支持一些常用的郵件協議,如前面所講的SMTP,POP3,IMAP,還有MIME等。我們在使用JavaMail API 編寫郵件時,無須考慮郵件的底層實現細節,只要調用JavaMail 開發包中相應的API類就可以了。
-
我們可以先嚐試發送一封簡單的郵件,確保電腦可以連接網絡。
創建包含郵件服務器的網絡連接信息的Session對象。
創建代表郵件內容的Message對象
創建Transport對象,連接服務器,發送Message,關閉連接
主要有四個核心類,我們在編寫程序時,記住這四個核心類,就很容易編寫出Java郵件處理程序。
純文本郵件
先在項目中導入jar包
QQ郵箱中獲取對應的權限
QQ郵箱需要安全驗證,我們需要獲取他對應的權限;
QQ郵箱–>郵箱設置–>賬戶
編寫測試代碼
package com.kuang.mail;
import com.sun.mail.util.MailSSLSocketFactory;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SendEmail {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.host", "smtp.qq.com"); //// 設置QQ郵件服務器
prop.setProperty("mail.transport.protocol", "smtp"); // 郵件發送協議
prop.setProperty("mail.smtp.auth", "true"); // 需要驗證用戶名密碼
// 關於QQ郵箱,還要設置SSL加密,加上以下代碼即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//使用JavaMail發送郵件的5個步驟
//創建定義整個應用程序所需的環境信息的 Session 對象
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//發件人郵件用戶名、授權碼
return new PasswordAuthentication("[email protected]", "授權碼");
}
});
//開啓Session的debug模式,這樣就可以查看到程序發送Email的運行狀態
session.setDebug(true);
//2、通過session得到transport對象
Transport ts = session.getTransport();
//3、使用郵箱的用戶名和授權碼連上郵件服務器
ts.connect("smtp.qq.com", "[email protected]", "授權碼");
//4、創建郵件
//創建郵件對象
MimeMessage message = new MimeMessage(session);
//指明郵件的發件人
message.setFrom(new InternetAddress("[email protected]"));
//指明郵件的收件人,現在發件人和收件人是一樣的,那就是自己給自己發
message.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]"));
//郵件的標題
message.setSubject("只包含文本的簡單郵件");
//郵件的文本內容
message.setContent("你好啊!", "text/html;charset=UTF-8");
//5、發送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
}
發送帶圖片和附件的郵件
先認識兩個類一個名詞:
MIME(多用途互聯網郵件擴展類型)
MimeBodyPart類
javax.mail.internet.MimeBodyPart類 表示的是一個MIME消息,它和MimeMessage類一樣都是從Part接口繼承過來。
MimeMultipart類
javax.mail.internet.MimeMultipart是抽象類 Multipart的實現子類,它用來組合多個MIME消息。一個MimeMultipart對象可以包含多個代表MIME消息的MimeBodyPart對象。
創建包含內嵌圖片的郵件
前面的例子中是單獨的使用HTML或者是純文本內容,但是有時候我們需要在純文本中使用內嵌的方式顯示一些圖片,因此就要將純文本和內嵌圖片單獨存放在MimeBodyPart中然後再將其存放在一個Mimemultipart對象中即可。
代碼實現;
package com.kuang.mail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
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 java.util.Properties;
public class SendImageEmail {
public static void main(String[] args) throws Exception {
Properties prop = new Properties();
prop.setProperty("mail.host", "smtp.qq.com"); //// 設置QQ郵件服務器
prop.setProperty("mail.transport.protocol", "smtp"); // 郵件發送協議
prop.setProperty("mail.smtp.auth", "true"); // 需要驗證用戶名密碼
// 關於QQ郵箱,還要設置SSL加密,加上以下代碼即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//使用JavaMail發送郵件的5個步驟
//1、創建定義整個應用程序所需的環境信息的 Session 對象
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//發件人郵件用戶名、授權碼
return new PasswordAuthentication("[email protected]", "授權碼");
}
});
//開啓Session的debug模式,這樣就可以查看到程序發送Email的運行狀態
session.setDebug(true);
//2、通過session得到transport對象
Transport ts = session.getTransport();
//3、使用郵箱的用戶名和授權碼連上郵件服務器
ts.connect("smtp.qq.com", "[email protected]", "授權碼");
//4、創建郵件
//創建郵件
MimeMessage message = new MimeMessage(session);
// 設置郵件的基本信息
//發件人
message.setFrom(new InternetAddress("[email protected]"));
//收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]"));
//郵件標題
message.setSubject("帶圖片的郵件");
// 準備郵件數據
// 準備圖片數據
MimeBodyPart image = new MimeBodyPart();
DataHandler dh = new DataHandler(new FileDataSource("src/resources/bz.jpg"));
image.setDataHandler(dh);
image.setContentID("bz.jpg");
// 準備正文數據
MimeBodyPart text = new MimeBodyPart();
text.setContent("這是一封郵件正文帶圖片<img src='cid:bz.jpg'>的郵件", "text/html;charset=UTF-8");
// 描述數據關係
MimeMultipart mm = new MimeMultipart();
mm.addBodyPart(text);
mm.addBodyPart(image);
mm.setSubType("related");
//設置到消息中,保存修改
message.setContent(mm);
message.saveChanges();
//5.發送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}
}
帶圖片和附件的複雜郵件發送
代碼實現:
package com.kuang.mail;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler;
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 java.security.GeneralSecurityException;
import java.util.Properties;
public class SendFileMail {
public static void main(String[] args) throws MessagingException, GeneralSecurityException {
//創建一個配置文件保存並讀取信息
Properties properties = new Properties();
//設置qq郵件服務器
properties.setProperty("mail.host","smtp.qq.com");
//設置發送的協議
properties.setProperty("mail.transport.protocol","smtp");
//設置用戶是否需要驗證
properties.setProperty("mail.smtp.auth", "true");
//=================================只有QQ存在的一個特性,需要建立一個安全的鏈接
// 關於QQ郵箱,還要設置SSL加密,加上以下代碼即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
properties.put("mail.smtp.ssl.enable", "true");
properties.put("mail.smtp.ssl.socketFactory", sf);
//=================================準備工作完畢
//1.創建一個session會話對象;
Session session = Session.getDefaultInstance(properties, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("[email protected]", "授權碼");
}
});
//可以通過session開啓Dubug模式,查看所有的過程
session.setDebug(true);
//2.獲取連接對象,通過session對象獲得Transport,需要捕獲或者拋出異常;
Transport tp = session.getTransport();
//3.連接服務器,需要拋出異常;
tp.connect("smtp.qq.com","[email protected]","授權碼");
//4.連接上之後我們需要發送郵件;
MimeMessage mimeMessage = imageMail(session);
//5.發送郵件
tp.sendMessage(mimeMessage,mimeMessage.getAllRecipients());
//6.關閉連接
tp.close();
}
public static MimeMessage imageMail(Session session) throws MessagingException {
//消息的固定信息
MimeMessage mimeMessage = new MimeMessage(session);
//郵件發送人
mimeMessage.setFrom(new InternetAddress("[email protected]"));
//郵件接收人,可以同時發送給很多人,我們這裏只發給自己;
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]"));
mimeMessage.setSubject("我也不知道是個什麼東西就發給你了"); //郵件主題
/*
編寫郵件內容
1.圖片
2.附件
3.文本
*/
//圖片
MimeBodyPart body1 = new MimeBodyPart();
body1.setDataHandler(new DataHandler(new FileDataSource("src/resources/yhbxb.png")));
body1.setContentID("yhbxb.png"); //圖片設置ID
//文本
MimeBodyPart body2 = new MimeBodyPart();
body2.setContent("請注意,我不是廣告<img src='cid:yhbxb.png'>","text/html;charset=utf-8");
//附件
MimeBodyPart body3 = new MimeBodyPart();
body3.setDataHandler(new DataHandler(new FileDataSource("src/resources/log4j.properties")));
body3.setFileName("log4j.properties"); //附件設置名字
MimeBodyPart body4 = new MimeBodyPart();
body4.setDataHandler(new DataHandler(new FileDataSource("src/resources/1.txt")));
body4.setFileName(""); //附件設置名字
//拼裝郵件正文內容
MimeMultipart multipart1 = new MimeMultipart();
multipart1.addBodyPart(body1);
multipart1.addBodyPart(body2);
multipart1.setSubType("related"); //1.文本和圖片內嵌成功!
//new MimeBodyPart().setContent(multipart1); //將拼裝好的正文內容設置爲主體
MimeBodyPart contentText = new MimeBodyPart();
contentText.setContent(multipart1);
//拼接附件
MimeMultipart allFile =new MimeMultipart();
allFile.addBodyPart(body3); //附件
allFile.addBodyPart(body4); //附件
allFile.addBodyPart(contentText);//正文
allFile.setSubType("mixed"); //正文和附件都存在郵件中,所有類型設置爲mixed;
//放到Message消息中
mimeMessage.setContent(allFile);
mimeMessage.saveChanges();//保存修改
return mimeMessage;
}
}
JavaWeb發送郵件
現在很多的網站都提供有用戶註冊功能, 通常我們註冊成功之後就會收到一封來自注冊網站的郵件。郵件裏面的內容可能包含了我們的註冊的用戶名和密碼以及一個激活賬戶的超鏈接等信息。今天我們也來實現一個這樣的功能,用戶註冊成功之後,就將用戶的註冊信息以Email的形式發送到用戶的註冊郵箱當中,實現發送郵件功能就得藉助於JavaMail了。
代碼實現:
新建一個JavaWeb項目,配置tomcat,添加jar包
1.編寫對應的用戶實體類
package com.kuang.pojo;
public class User {
private String username;
private String password;
private String email;
public User() {
}
public User(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
}
2.前端註冊頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>註冊</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/RegisterServlet.do" method="post">
用戶名:<input type="text" name="username"><br/>
密碼:<input type="password" name="password"><br/>
郵箱:<input type="text" name="email"><br/>
<input type="submit" value="註冊">
</form>
</body>
</html>
3.郵件發送工具類
package com.kuang.utils;
import com.kuang.pojo.User;
import com.sun.mail.util.MailSSLSocketFactory;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class Sendmail extends Thread {
//用於給用戶發送郵件的郵箱
private String from = "[email protected]";
//郵箱的用戶名
private String username = "[email protected]";
//郵箱的密碼
private String password = "授權碼";
//發送郵件的服務器地址
private String host = "smtp.qq.com";
private User user;
public Sendmail(User user){
this.user = user;
}
//重寫run方法的實現,在run方法中發送郵件給指定的用戶
@Override
public void run() {
try{
Properties prop = new Properties();
prop.setProperty("mail.host", host);
prop.setProperty("mail.transport.protocol", "smtp");
prop.setProperty("mail.smtp.auth", "true");
// 關於QQ郵箱,還要設置SSL加密,加上以下代碼即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
//1、創建定義整個應用程序所需的環境信息的 Session 對象
Session session = Session.getDefaultInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//發件人郵件用戶名、授權碼
return new PasswordAuthentication("[email protected]", "授權碼");
}
});
//開啓Session的debug模式,這樣就可以查看到程序發送Email的運行狀態
session.setDebug(true);
//2、通過session得到transport對象
Transport ts = session.getTransport();
//3、使用郵箱的用戶名和授權碼連上郵件服務器
ts.connect(host, username, password);
//4、創建郵件
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from)); //發件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); //收件人
message.setSubject("用戶註冊郵件"); //郵件的標題
String info = "恭喜您註冊成功,您的用戶名:" + user.getUsername() + ",您的密碼:" + user.getPassword() + ",請妥善保管,如有問題請聯繫網站客服!!";
message.setContent(info, "text/html;charset=UTF-8");
message.saveChanges();
//發送郵件
ts.sendMessage(message, message.getAllRecipients());
ts.close();
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4.編寫對應的servlet處理類
package com.kuang.servlet;
import com.kuang.pojo.User;
import com.kuang.utils.Sendmail;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegisterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//接收用戶請求,封裝成對象
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
User user = new User(username,password,email);
//用戶註冊成功之後,給用戶發送一封郵件
//我們使用線程來專門發送郵件,防止出現耗時,和網站註冊人數過多的情況;
Sendmail send = new Sendmail(user);
//啓動線程,線程啓動之後就會執行run方法來發送郵件
send.start();
//註冊用戶
request.setAttribute("message", "註冊成功,我們已經發了一封帶了註冊信息的電子郵件,請查收!如網絡不穩定,可能過會兒才能收到!!");
request.getRequestDispatcher("info.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("message", "註冊失敗!!");
request.getRequestDispatcher("info.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5.配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>register</servlet-name>
<servlet-class>com.kuang.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>register</servlet-name>
<url-pattern>/RegisterServlet.do</url-pattern>
</servlet-mapping>
</web-app>
6.發送成功或失敗的反饋頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>提示信息</title>
</head>
<body>
${message}
</body>
</html>
運行Tomcat測試!
郵件發送成功,OK!