-
邮件发送和接收的协议
SMTP协议 (Simple Mail Transfer Protocol)
- 属于TCP/IP协议族。
- 控制信件的中转方式,帮助每台计算机在发送或中转信件时找到下一个目的地。
- SMTP服务器是遵循SMTP协议的发送邮件服务器。
POP3协议 (Post Office Protocol - Version 3)
- 属于TCP/IP协议族。
- 用于远程管理在服务器上的电子邮件,帮助用户登录到邮件服务器上、取邮件、删邮件等。
- POP服务器是遵循POP协议的邮件接收服务器。
-
邮件服务器
要在网络上实现邮件功能,要使用专门的邮件服务器。
- SMTP服务器 :一般是smtp.xxx.com。如163邮箱smtp.163.com,QQ邮箱smtp.qq.com。
- POP服务器:一般是pop.xxx.com。如163邮箱pop.163.com,QQ邮箱pop.qq.com。
-
原理图
1. 用户A通过SMTP协议连接到SMTP服务器,发送邮件到QQ邮箱的SMTP服务器;
2. QQ邮箱的SMTP服务器,通过SMTP协议将邮件中转到网易邮箱的SMTP服务器;
3. 网易邮箱的SMTP服务器,将接收到的邮件存储在B的邮箱账号的邮箱空间中;
4. 用户B通过POP3协议连接到POP服务器,请求收取邮件;
5. POP服务器从B的邮箱账号的邮箱空间中取出邮件;
6. POP服务器将取出来的邮件给B。
-
用java简单邮件发送实现(qq邮件)
需要依赖的jar包:
- javaMail API
- java Activation Framework
package com.email; 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 MailSendDemo { 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); //1.创建定义整个应用程序所需的环境信息的session对象 //只有qq邮箱有 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", "发信人邮箱@qq.com", "授权码"); //4.创建邮件 //需要传递session MimeMessage message = new MimeMessage(session); //发件人 message.setFrom(new InternetAddress("发信人邮箱@qq.com")); //收件人 message.setRecipient(Message.RecipientType.TO, new InternetAddress("收信人邮箱@qq.com")); //设置邮件的主体 message.setSubject("简单邮件"); //设置邮件的内容 //同样可以设置样式 message.setContent("你好啊", "text/html;charset=UTF-8"); //5.发送邮件 ts.sendMessage(message, message.getAllRecipients()); //6.关闭连接 ts.close(); } }
-
用java实现复杂邮件发送,复杂邮件指的是:邮件内容既有文本,又有图片还有附件。
/** * 创建复杂邮件 * 相比普通邮件增加:图片和附件(需要数据处理,设置CID和附件名)、描述数据关系、设置并保存修改 * * @param session Session对象 * @param addresser 发件人 * @param addressee 收件人 * @return 复杂邮件 */ private MimeMessage makeMixedMessage(Session session, String addresser, String addressee) throws MessagingException { MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(addresser)); // 发件人 message.setRecipient(Message.RecipientType.TO, new InternetAddress(addressee)); // 收件人 message.setSubject("Java实现邮件发送:复杂邮件"); // 邮件主题 // 邮件内容 // 1、正文 MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent("复杂邮件的正文,<img src='cid:a'>附带一张图片", "text/html;charset=utf-8"); // 2、图片 MimeBodyPart imgPart = new MimeBodyPart(); DataHandler dh = new DataHandler(new FileDataSource("src\\main\\resources\\img\\a.jpg")); imgPart.setDataHandler(dh); // 需要数据处理 imgPart.setContentID("a"); // 设置CID // 3、附件 MimeBodyPart attachPart = new MimeBodyPart(); DataHandler dh1 = new DataHandler(new FileDataSource("src\\main\\resources\\test\\test.md")); attachPart.setDataHandler(dh1); // 需要数据处理 attachPart.setFileName("file.md"); // 设置附件名,最好包含后缀名 // 描述数据关系:alternative/related/mixed MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(textPart); mm.addBodyPart(imgPart); mm.addBodyPart(attachPart); mm.setSubType("mixed"); // 设置到消息中,保存修改 message.setContent(mm); message.saveChanges(); return message; }
-
Java Web中的邮件发送
//servlet public class RegisterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取参数 String username = req.getParameter("username"); String password = req.getParameter("password"); String mail = req.getParameter("mail"); User user = new User(username, password, mail); // 启动线程来发送邮件,优化注册等待时间 MailThread mailThread = new MailThread(user); mailThread.start(); // start()才是开启多线程,run()只是调用方法 req.setAttribute("msg","注册成功,稍后会收到一封邮件"); req.getRequestDispatcher("success.jsp").forward(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } //User类 public class User { private String username; // 账户 private String password; // 密码 private String mailAddress; // 邮箱地址 } //多线程实现邮件发送 /* 多线程实现邮件发送的意义: 如果不用多线程,在邮件成功发出后,程序才会继续运行; 用户体验差,等待时间长; 使用多线程优化,在完成注册后程序继续运行(如跳转页面等),邮件发送在单独的线程中完成。 */ public class MailThread extends Thread { final private String host = "smtp.qq.com"; // 服务器主机号 final private String authCode = "xxx"; // 授权码 final private String addresser = "[email protected]"; // 发件人邮箱 final private User user; public MailThread(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"); // 权限:验证用户名、授权码 // SSL加密:QQ邮箱需要设置,通过以下4行代码 MailSSLSocketFactory mssf = null; mssf = new MailSSLSocketFactory(); mssf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable", "true"); prop.put("mail.smtp.ssl.socketFactory", mssf); // 1、创建Session对象 Session session = Session.getDefaultInstance(prop, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(addresser, authCode); } }); session.setDebug(true); // 开启Debug模式 // 2、获得Transport对象 Transport transport = session.getTransport(); transport.connect(host, addresser, authCode); // 3、创建邮件:调用相应方法(纯文本/内嵌资源/带附件) MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(addresser)); // 发件人 message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getMailAddress())); // 收件人 message.setSubject("用户注册邮件"); // 邮件主题 String info = "注册成功,您的用户名:" + user.getUsername() + ",密码:" + user.getPassword(); // 邮件内容 message.setContent(info, "text/html;charset=utf-8"); // 4、发送邮件 transport.sendMessage(message, new InternetAddress[]{new InternetAddress(user.getMailAddress())}); // 关闭邮件服务器 transport.close(); } catch (GeneralSecurityException | MessagingException e) { e.printStackTrace(); } } } //注册servlet <servlet> <servlet-name>RegisterServlet</servlet-name> <servlet-class>com.test.mail.RegisterServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RegisterServlet</servlet-name> <url-pattern>/register.do</url-pattern> </servlet-mapping>