邮件发送的三种方式maven、javaWeb和SpringBoot——让邮件发送玩得转起来

邮箱发送

要在网上实现邮件功能,需有专门的邮件服务器。

这些邮件服务器类似生活中的邮局,主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。

SMTP服务器地址:一般是smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com

电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请。比如我们要使用QQ邮箱,就需要开通邮箱功能。

邮件发送原理图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y0jt3Kxh-1640676407870)(邮箱发送.assets/image-20211216075545777.png)]

下载依赖

  • mail-1.4.7.jar
  • activation-1.1.1.jar

在这里插入图片描述

<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

授权码的获取

在这里插入图片描述

在这里插入图片描述

设置 -> 账户 -> POP3/SMTP服务 -> 开启 -> 密保手机验证即可->开启成功

简易文本邮件发送实现

在这里插入图片描述

由上图我们可以确定几个必须步骤

1.创建session对象

2.创建Transport对象

3.使用邮箱的用户名和授权码连上邮件服务器

4.创建一个Message对象(需要传递session)

message需要指明发件人、收件人以及文件内容
5.发送邮件

6.关闭连接

编码

package com.hopeful.mail;

import com.sun.mail.util.MailSSLSocketFactory;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.Properties;

/**
 * MailDemo1
 *  kigdmdfveaymgfac
 * @author : yl
 * @version : [v1.0]
 * @createTime : [2021/12/16 7:53]
 */
public class MailDemo1 {
    public static void main(String[] args) throws Exception {
        Properties prop = new Properties();
        // 设置QQ邮件服务器
        prop.setProperty("mail.host","smtp.qq.com");
        // 邮件发送协议
        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() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 发送短信的授权码
                return new PasswordAuthentication("xxxx@qq.com", "授权码");
            }
        });

        // 开启session的debug模式,这样可以查看程序发送Email的运行状态
        session.setDebug(true);

        // 2.通过session得倒transport的对象
        Transport ts = session.getTransport();

        // 3.使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com","xxxxx@qq.com","授权码");  // 发送短信的授权码

        // 4.创建邮件:写文件
        MimeMessage message = new MimeMessage(session);
        // 指明邮件的发送人
        message.setFrom(new InternetAddress("xxxxx@qq.com"));
        // 指明邮件的收件人
        // 通过数组指定多个人
        InternetAddress address1 = new InternetAddress("xxxxx@qq.com");
        InternetAddress address2 = new InternetAddress("yyyyy@qq.com");
        InternetAddress[] addresses = {address1,address2};
        message.setRecipients(Message.RecipientType.TO,addresses);
        // 发送一个人
//        message.setRecipient(Message.RecipientType.TO, new InternetAddress("2041491265@qq.com"));
        // 邮件标题
        message.setSubject("测试邮件发送");
        // 邮件的文本内容
        message.setContent("hello World! I'm comming.... 你好,世界,我来了","text/html;charset=utf-8");
        // 5.发送邮件
        ts.sendMessage(message,message.getAllRecipients());

        // 6.关闭连接
        ts.close();

    }

}

测试结果
在这里插入图片描述

复杂邮件发送(图片附件)

复杂文件构成

在这里插入图片描述

复杂邮件发送和简单邮件发送类似,只是多了文件或附件的处理。也就是邮件内容也被分为很多个部分,由文件、图片、附件等构成,编写邮件内容的过程,类似于积木的拼接,另外值得注意的是文本内容一般为HTML的格式发送。

每一个文本、图片、附件可以分为一个MimeBodyPart,由MimeMultipart完成组装

依赖

<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

编码

package com.hopeful.mail;

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;

/**
 * Mail
 *
 * @author : yl
 * @version : [v1.0]
 * @createTime : [2021/12/22 6:19]
 */
public class MailDemo02 {
    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() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("1505423401@qq.com", "kigdmdfveaymgfac");
            }
        });

        // 开启session的debug模式,这样可以查看程序发送Email的运行状态
        session.setDebug(true);
        // 2.通过session得到transport对象
        Transport ts = session.getTransport();
        // 3.使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com","1505423401@qq.com", "kigdmdfveaymgfac");

        // 4.创建邮件:写文件
        MimeMessage message = new MimeMessage(session);

        // 指明邮件发件人
        message.setFrom(new InternetAddress("1505423401@qq.com"));
        // 指明邮件接收人
        message.setRecipient(Message.RecipientType.TO,new InternetAddress("xxxxx@qq.com"));
        // 邮件标题
        message.setSubject("java发送复杂内容的邮件");


        // 邮件文本内容发送
        // ========================================准备图片数据=====================================================
        MimeBodyPart image = new MimeBodyPart();
        // 图片需要经过数据化处理(手机上查看邮箱图片无法显示)
        DataHandler dh = new DataHandler(new FileDataSource("D:\\xxxx\邮箱发送.assets\\image-20211216075545777.png"));
        // 在part中放入这个处理过图片的数据
        image.setDataHandler(dh);

        // 给这个part设置一个ID名字
        image.setContentID("bz.png");

        // 准备正文数据
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("这是我在测试java发送复杂文件,插入图片如下:<img src='cid:bz.png'>","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();
    }
}

注意:手机QQ查看邮箱图片无法显示

网站邮箱验证注册

页面

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<form action="${pageContext.request.contextPath}/RegisterServlet.do" method="post">
  用户名:<input type="text" name="username">
  密码:<input type="password" name="pwd">
  邮箱:<input type="text" name="email">
  <input type="submit" value="注册">

</form>
</body>
</html>

info.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h2>${msg}</h2>
</body>
</html>

后台编码

实体类

package com.hopeful.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 + '\'' +
                '}';
    }
}

邮件发送类(多线程)

package com.hopeful.mail;


import com.hopeful.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="xxxxx@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);///设置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() {
                @Override
                protected javax.mail.PasswordAuthentication getPasswordAuthentication() {
                    return new javax.mail.PasswordAuthentication(from,"kigdmdfveaymgfac");
                }
            });
            //开启session的debug模式,这样可以查看到程序发送Email的运行状态
            session.setDebug(true);
            //2.通过session得到transport对象
            Transport ts=session.getTransport();
            //3.使用邮箱的用户名和授权码连上邮件服务器
            ts.connect(host,from,"kigdmdfveaymgfac");
            //4.创建邮件:写文件
            //注意需要传递session
            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");
            //5.发送邮件
            ts.sendMessage(message,message.getAllRecipients());

            //6.关闭连接
            ts.close();
        }catch (Exception e){
            System.out.println(e);
        }

    }
}

servlet

package com.hopeful.pojo.servlet;

import com.hopeful.mail.SendMail;
import com.hopeful.pojo.User;

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 req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");
        String email = req.getParameter("email");

        User user = new User(username, pwd, email);
        SendMail sendMail = new SendMail(user);
        sendMail.start();
        System.out.println("success");

        // 注册用户
        req.setAttribute("msg","注册成功,我们已发送一封含有链接的电子邮件,请通过邮件激活");
        req.getRequestDispatcher("info.jsp").forward(req,resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml配置请求接口

<servlet>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>com.hopeful.pojo.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/RegisterServlet.do</url-pattern>
</servlet-mapping>

常见问题

java.lang.NoClassDefFoundError:javax/mail/Authenticator问题解决

在这里插入图片描述

分析:

1.jar包版本问题(检查jar版本)

2.jar包没有加到library (将jar包加入到library)

3.tomcat lib 中没有引入上面两个jar包(我的是这个问题)(将jar包加入到tomcat安装目录lib目录中)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GvHtC7yQ-1640676407880)(邮箱发送.assets/image-20211223062239850.png)]

添加后,重启tomcat成功!

springboot项目实现邮件发送(超简单)

依赖

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

application.propeties

# 配置QQ邮箱地址
spring.mail.host=smtp.qq.com
# 配置发送邮箱的地址
spring.mail.username=xxxx@qq.com
# 配置stmp发送验证码(注意不是QQ密码)
spring.mail.password=xxxxxx
# 开启安全验证
spring.mail.properties.mail.smtp.ssl.enable=true

编码

package com.hopeful.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMailMessage;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;

@SpringBootTest
class MailSpringDemoApplicationTests {

    @Autowired
    JavaMailSender mailSender;

    /**
     * 简单邮件发送
     */
    @Test
    void contextLoads() {

        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("SpringBoot发送短信测试");
        message.setText("Hello SpringBoot Email!");

        message.setFrom("xxxx@qq.com");
        message.setTo("xxxx@qq.com");

        mailSender.send(message);
    }

    /**
     * 复杂邮件发送
     */
    @Test
    public void testEmail() throws MessagingException {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setSubject("SpringBoot发送复杂短信测试");
        helper.setText("<h2>Hello SpringBoot Email!</h2>",true);

        helper.addAttachment("1.png", new File("C:\\Users\\Apple\\Desktop\\邮箱发送.assets\\邮件发送.png"));
        helper.addAttachment("2.png", new File("C:\\Users\\Apple\\Desktop\\邮箱发送.assets\\image-20211217080106125.png"));


        helper.setFrom("xxxx@qq.com");
        helper.setTo("xxxx@qq.com");

        mailSender.send(mimeMessage);
    }


}

不太理解的可参考视频(40/41 邮件发送章节):
邮件发送视频

看到这里,希望多多支持!你的鼎力支持,是我不懈的动力!点赞加关注!精彩实用干货持续更新中。。。