jar包的支持
核心功能jar包
activation-1.1.1.jar
mail-1.4.7.jar
邮件发送原理图
授权码的获取
简易文本邮件发送的实现(只有文本、一般是超文本类型)
由上图我们可以确定几个必须步骤
1.创建session对象
2.创建Transport对象
3.使用邮箱的用户名和授权码连上邮件服务器
4.创建一个Message对象(需要传递session)
5.发送邮件
6.关闭连接
仅包含文本的发送
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
| 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 MailDemo01 { public static void main(String[] args) throws Exception { Properties prop=new Properties(); prop.setProperty("mail.host","smtp.qq.com"); prop.setProperty("mail.transport.protocol","smtp"); prop.setProperty("mail.smtp.auth","true"); MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf);
Session session=Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("XXXX@qq.com","授权码"); } }); session.setDebug(true); Transport ts=session.getTransport(); ts.connect("smtp.qq.com","XXXX@qq.com","授权码"); MimeMessage message=new MimeMessage(session); message.setFrom(new InternetAddress("XXXX@qq.com")); message.setRecipient(Message.RecipientType.TO,new InternetAddress("XXXX@qq.com")); message.setSubject("发送的标题"); message.setContent("内容","text/html;charset=UTF-8"); ts.sendMessage(message,message.getAllRecipients());
ts.close();
} }
|
必要配置信息:
注意:QQ等大厂的邮箱需要有几点注意:
复杂文件内容的发送(含有图片、附件等)
文件构成解析
除了邮件内容部分,其他的部分代码往往是相同的,除了需要根据不同的邮箱运营商编写不同的配置代码外。邮件内容也被分为很多个部分,由文件、图片、附件等构成,编写邮件内容的过程,类似于积木的拼接,另外值得注意的是文本内容一般为HTML的格式发送。
每一个文本、图片、附件可以分为一个MimeBodyPart,由MimeMultipart完成组装
包含图片的发送
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
| 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 MailDemo02 { public static void main(String[] args) throws Exception { Properties prop=new Properties(); prop.setProperty("mail.host","smtp.qq.com"); prop.setProperty("mail.transport.protocol","smtp"); prop.setProperty("mail.smtp.auth","true"); MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf);
Session session=Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("11927XXX@qq.com","授权码"); } }); session.setDebug(true); Transport ts=session.getTransport(); ts.connect("smtp.qq.com","11927XXX@qq.com","授权码"); MimeMessage message=new MimeMessage(session); message.setFrom(new InternetAddress("11927XXX@qq.com")); message.setRecipient(Message.RecipientType.TO,new InternetAddress("11927XXX@qq.com")); message.setSubject("java发出");
MimeBodyPart image=new MimeBodyPart(); DataHandler dh=new DataHandler(new FileDataSource("D:\\Bert\\1594126632(1).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(); ts.sendMessage(message,message.getAllRecipients());
ts.close();
} }
|
包含附件的发送
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
| import com.sun.mail.util.MailSSLSocketFactory;
import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.*; import java.util.Properties;
public class MailDemo03 { public static void main(String[] args) throws Exception { Properties prop=new Properties(); prop.setProperty("mail.host","smtp.qq.com"); prop.setProperty("mail.transport.protocol","smtp"); prop.setProperty("mail.smtp.auth","true"); MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf);
Session session=Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("1192XXXX@qq.com","授权码"); } }); session.setDebug(true); Transport ts=session.getTransport(); ts.connect("smtp.qq.com","1192XXXX@qq.com","授权码"); MimeMessage message=new MimeMessage(session); message.setFrom(new InternetAddress("1192XXXX@qq.com")); message.setRecipient(Message.RecipientType.TO,new InternetAddress("1192XXXX@qq.com")); message.setSubject("java发出");
MimeBodyPart image=new MimeBodyPart(); DataHandler dh=new DataHandler(new FileDataSource("D:\\Bert\\1594126632(1).jpg")); image.setDataHandler(dh); image.setContentID("bz.jpg");
MimeBodyPart text=new MimeBodyPart(); text.setContent("这是一张正文<img src='cid:bz.jpg'>","text/html;charset=UTF-8");
MimeBodyPart body1= new MimeBodyPart(); body1.setDataHandler(new DataHandler(new FileDataSource("D:\\Bert\\cmd.txt"))); body1.setFileName("1.txt");
MimeMultipart mm=new MimeMultipart(); mm.addBodyPart(body1); mm.addBodyPart(text); mm.addBodyPart(image); mm.setSubType("mixed");
message.setContent(mm); message.saveChanges(); ts.sendMessage(message,message.getAllRecipients());
ts.close();
} }
|
实战:注册通知邮件
index.JSP
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <html> <body> <h2>Hello World!</h2> <form action="${pageContext.request.contextPath}/RegisterServlet.do" method="post"> 用户名:<input type="text" name="username"> 密码:<input type="text" name="pwd"> 邮箱:<input type="text" name="email"> <input type="submit" value="注册">
</form> </body> </html>
|
实体类
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
| 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 + '\'' + '}'; } }
|
绑定路径
1 2 3 4 5 6 7 8
| <servlet> <servlet-name>RegisterServlet</servlet-name> <servlet-class>cn.csn.MailDemo01.servlet.RegisterServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RegisterServlet</servlet-name> <url-pattern>/RegisterServlet.do</url-pattern> </servlet-mapping>
|
servlet
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
| import cn.csn.MailDemo01.pojo.User; import cn.csn.MailDemo01.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 doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username=req.getParameter("username"); String password=req.getParameter("pwd"); String email=req.getParameter("email");
User user=new User(username,password,email); Sendmail send=new Sendmail(user); send.start(); System.out.println("success");
}
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
|
发送邮件核心类
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
| import cn.csn.MailDemo01.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="XXX@qq.com";
private String host="smtp.qq.com";
private User user;
public Sendmail(User user){ this.user=user; } @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"); MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf);
Session session= Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(from,"授权码"); } }); session.setDebug(true); Transport ts=session.getTransport(); ts.connect(host,from,"授权码"); MimeMessage message=new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.setRecipient(Message.RecipientType.TO,new InternetAddress(user.getEmail())); message.setSubject("注册通知"); message.setContent("恭喜你("+user.getUsername()+")成功注册!"+"密码:"+user.getPassword() ,"text/html;charset=UTF-8"); ts.sendMessage(message,message.getAllRecipients());
ts.close(); }catch (Exception e){ System.out.println(e); }
} }
|
这里引入多线程的目的是为了提高用户的体验,防止因发送文件时间过长,导致前端响应过久,因此这里采用异步响应。