java实现发送邮件

发送邮件

基本概念

上图只是一个简单的流程演示,并不一定完全正确。

发送和接受邮件的规则(所有的邮箱都遵循这个规则):

SMTP协议:发送邮件;

POP3协议:接收邮件。

开通方法

QQ邮箱、网易邮箱的开通都在设置里。

代码演示

JavaMail 是sun公司(现以被甲骨文收购)为方便Java开发人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,如前面所讲的SMTP,POP3,IMAP,还有MIME等。我们在使用JavaMail API 编写邮件时,无须考虑邮件的底层实现细节,只要调用JavaMail 开发包中相应的API类就可以了。

我们可以先尝试发送一封简单的邮件,确保电脑可以连接网络。

  • 创建包含邮件服务器的网络连接信息的Session对象。

  • 创建代表邮件内容的Message对象

  • 创建Transport对象,连接服务器,发送Message,关闭连接

主要有四个核心类,我们在编写程序时,记住这四个核心类,就很容易编写出Java邮件处理程序。

简单发送邮件--纯文本,无附件

jar包

xml 复制代码
<dependency>
  <groupId>javax.activation</groupId>
  <artifactId>activation</artifactId>
  <version>1.1.1</version>
</dependency>

<dependency>
  <groupId>javax.mail</groupId>
  <artifactId>mail</artifactId>
  <version>1.4.7</version>
</dependency>
java 复制代码
//发送一封简单的邮件
public class MailDemo01 {
    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 对象
        //使用QQ邮箱的时候才需要,其他邮箱不需要这一段代码
        Session session = Session.getDefaultInstance(prop, new Authenticator() {//获取和SMTP服务器的连接对象
            public PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("XXXX@qq.com", "授权码");
            }
        });

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

        //2、通过session得到transport对象
        Transport ts = session.getTransport();//通过这一次和SMTP服务器的连接对象获取发送邮件的传输对象

        //3、使用邮箱的用户名和授权码连上SMTP邮件服务器,即登陆
        ts.connect("smtp.qq.com", "XXXX@qq.com", "授权码");

        //4、创建邮件对象MimeMessage------点击网页上的写信
        //创建一个邮件对象
        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("<h2 style='color:red'>你好啊!</h2>", "text/html;charset=UTF-8");//设置邮件的具体内容

        //5、发送邮件------在网页上点击发送按钮
        ts.sendMessage(message, message.getAllRecipients());

        //6、关闭连接对象,即关闭服务器上的连接资源
        ts.close();
    }
}

发送带有图片的邮件

java 复制代码
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 PictureMailQQ {

    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 对象
        //使用QQ邮箱的时候才需要,其他邮箱不需要这一段代码
        Session session = Session.getDefaultInstance(prop, new Authenticator() {//获取和SMTP服务器的连接对象
            public PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("邮箱地址", "授权码");
            }
        });

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

        //2、通过session得到transport对象
        Transport ts = session.getTransport();//通过这一次和SMTP服务器的连接对象获取发送邮件的传输对象

        //3、使用邮箱的用户名和授权码连上SMTP邮件服务器,即登陆
        ts.connect("smtp.qq.com", "邮箱地址", "授权码");

        //4、创建邮件对象MimeMessage------点击网页上的写信
        //创建一个邮件对象
        MimeMessage message = new MimeMessage(session);
        //指明邮件的发件人------在网页上填写发件人
        message.setFrom(new InternetAddress("邮箱地址"));//设置发件人
        //指明邮件的收件人,现在发件人和收件人是一样的,那就是自己给自己发------在网页上填写收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("邮箱地址"));//设置收件人
        //邮件的标题------在网页上填写邮件标题
        message.setSubject("带有图片的邮件发送实现");//设置邮件主题
        //===========================================================================
        // 准备图片数据
        MimeBodyPart image = new MimeBodyPart();//获取一个图片的MimeBodyPart对象
        DataHandler dh = new DataHandler(new FileDataSource("图片路径"));//由于图片需要字符化才能传输,所以需要获取一个DataHandler对象
        image.setDataHandler(dh);//将图片序列化
        image.setContentID("12580.png");//为图片的MimeBodyPart对象设置一个ID,我们在文字中就可以使用它了

        // 准备正文数据
        MimeBodyPart text = new MimeBodyPart();//获取一个文本的MimeBodyPart对象
        text.setContent("这是一封邮件正文带图片的邮件<br><img src='cid:12580.png'>", "text/html;charset=UTF-8");//设置文本内容

        // 描述数据关系
        MimeMultipart mm = new MimeMultipart();//获取MimeMultipart
        mm.addBodyPart(text);//将文本MimeBodyPart对象加入MimeMultipart中
        mm.addBodyPart(image);//将图片MimeBodyPart对象加入MimeMultipart中
        mm.setSubType("related");//设置MimeMultipart对象的相对熟悉为related,即发送的数据为文本+非附件资源

        //设置到消息中,保存修改
        message.setContent(mm);//将MimeMultipart放入消息对象中
        message.saveChanges();//保存上面的修改

        //===========================================================================

        //5、发送邮件------在网页上点击发送按钮
        ts.sendMessage(message, message.getAllRecipients());

        //6、关闭连接对象,即关闭服务器上的连接资源
        ts.close();
    }
}

发送带有附件的邮件

java 复制代码
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;

/**
 * @author Zhang
 * @version 1.0
 */
public class AttachedMailQQ {

    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 对象
        //使用QQ邮箱的时候才需要,其他邮箱不需要这一段代码
        Session session = Session.getDefaultInstance(prop, new Authenticator() {//获取和SMTP服务器的连接对象
            public PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("邮箱地址", "授权码");
            }
        });

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

        //2、通过session得到transport对象
        Transport ts = session.getTransport();//通过这一次和SMTP服务器的连接对象获取发送邮件的传输对象

        //3、使用邮箱的用户名和授权码连上SMTP邮件服务器,即登陆
        ts.connect("smtp.qq.com", "邮箱地址", "授权码");

        //4、创建邮件对象MimeMessage------点击网页上的写信
        //创建一个邮件对象
        MimeMessage message = new MimeMessage(session);
        //指明邮件的发件人------在网页上填写发件人
        message.setFrom(new InternetAddress("邮箱地址"));//设置发件人
        //指明邮件的收件人,现在发件人和收件人是一样的,那就是自己给自己发------在网页上填写收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("邮箱地址"));//设置收件人
        //邮件的标题------在网页上填写邮件标题
        message.setSubject("发送附件邮件");//设置邮件主题
        //===========================================================================
        // 准备图片数据
        MimeBodyPart image = new MimeBodyPart();//获取一个图片的MimeBodyPart对象
        DataHandler dh = new DataHandler(new FileDataSource("附件地址"));//由于图片需要字符化才能传输,所以需要获取一个DataHandler对象
        image.setDataHandler(dh);//将图片序列化
        image.setContentID("12580.png");//为图片的MimeBodyPart对象设置一个ID,我们在文字中就可以使用它了

        // 准备正文数据
        MimeBodyPart text = new MimeBodyPart();//获取一个文本的MimeBodyPart对象
        text.setContent("这是一封邮件正文带图片的邮件<br><img src='cid:12580.png'>", "text/html;charset=UTF-8");//设置文本内容

        //附件
        MimeBodyPart attached = new MimeBodyPart();
        attached.setDataHandler(new DataHandler(new FileDataSource("附件地址")));
        attached.setFileName("attached.txt"); //附件设置名字---这个地方如果附件的名字没有文件格式,收到邮件后的附件会没有后缀名


        // 描述数据关系
        MimeMultipart mm = new MimeMultipart();//获取MimeMultipart
        mm.addBodyPart(text);//将文本MimeBodyPart对象加入MimeMultipart中
        mm.addBodyPart(image);//将图片MimeBodyPart对象加入MimeMultipart中
        mm.addBodyPart(attached);//附件
        mm.setSubType("mixed");//设置MimeMultipart对象的相对熟悉为related,即发送的数据为文本+非附件资源

        //设置到消息中,保存修改
        message.setContent(mm);//将MimeMultipart放入消息对象中
        message.saveChanges();//保存上面的修改

        //===========================================================================

        //5、发送邮件------在网页上点击发送按钮
        ts.sendMessage(message, message.getAllRecipients());

        //6、关闭连接对象,即关闭服务器上的连接资源
        ts.close();
    }
}

发送附件和图片邮件的说明

本质都是在MimeBodyPart对象中,设置的属性不同;图片可以通过以下方式直接展示出来,也可以当做附件发送。

java 复制代码
//附件
MimeBodyPart attached = new MimeBodyPart();
attached.setDataHandler(new DataHandler(new FileDataSource("附件地址")));
attached.setFileName("attached.txt"); //附件设置名字---这个地方如果附件的名字没有文件格式,收到邮件后的附件会没有后缀名

//图片
MimeBodyPart image = new MimeBodyPart();//获取一个图片的MimeBodyPart对象
DataHandler dh = new DataHandler(new FileDataSource("附件地址"));//由于图片需要字符化才能传输,所以需要获取一个DataHandler对象
image.setDataHandler(dh);//将图片序列化
image.setContentID("12580.png");//为图片的MimeBodyPart对象设置一个ID,我们在文字中就可以使用它了

//文本
MimeBodyPart text = new MimeBodyPart();//获取一个文本的MimeBodyPart对象
text.setContent("这是一封邮件正文带图片的邮件<br><img src='cid:12580.png'>", "text/html;charset=UTF-8");//设置文本内容

带有直接展示的图片和附件设置属性的区别:

**注意:**如果附件的名字没有文件格式,收到邮件后的附件会没有后缀名

java 复制代码
attached.setFileName("attached.txt");
java 复制代码
MimeMultipart mm = new MimeMultipart();//获取MimeMultipart
mm.setSubType("mixed");//带有附件的邮件属性为  mixed
mm.setSubType("mixed");//带有图片的邮件属性为  related

登录成功发送邮件的实现

为什么要用多线程去异步实现?

网站三秒钟原则:当响应超过3秒钟,99%的用户都会关闭、刷新或者进行其他操作,使用异步处理可以给用户更好的体验。

java 复制代码
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String mailAddress = req.getParameter("mailAddress");

        User user = new User();
        user.setPassword(password);
        user.setUsername(username);
        user.setMailAddress(mailAddress);
        System.out.println(user.toString());

        SendMail sendMail = new SendMail(user);
        sendMail.start();//调用线程发送邮件,防止发送时间较长,用户一直等待

        req.setAttribute("msg","注册成功,邮件已发送,请注意查收!如遇网络不稳定,请稍后查看!");
        req.getRequestDispatcher("success.jsp").forward(req,resp);
    }
}
java 复制代码
public class SendMail extends Thread{
    private User user;
    
    public SendMail(User user){
        this.user = user;
    }
    
    @Override
    public void run(){
        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加密,加上以下代码即可
        try {
            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 对象
            //使用QQ邮箱的时候才需要,其他邮箱不需要这一段代码
            Session session = Session.getDefaultInstance(prop, new Authenticator() {//获取和SMTP服务器的连接对象
                public PasswordAuthentication getPasswordAuthentication() {
                    //发件人邮件用户名、授权码
                    return new PasswordAuthentication("邮箱地址", "授权码");
                }
            });

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

            //2、通过session得到transport对象
            Transport ts = session.getTransport();//通过这一次和SMTP服务器的连接对象获取发送邮件的传输对象

            //3、使用邮箱的用户名和授权码连上SMTP邮件服务器,即登陆
            ts.connect("smtp.qq.com", "邮箱地址", "授权码");

            //4、创建邮件对象MimeMessage------点击网页上的写信
            //创建一个邮件对象
            MimeMessage message = new MimeMessage(session);
            //指明邮件的发件人------在网页上填写发件人
            message.setFrom(new InternetAddress("邮箱地址"));//设置发件人
            //指明邮件的收件人,现在发件人和收件人是一样的,那就是自己给自己发------在网页上填写收件人
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getMailAddress()));//设置收件人
            //邮件的标题------在网页上填写邮件标题
            message.setSubject("简单邮件发送实现");//设置邮件主题
            //邮件的文本内容------在网页上填写邮件内容
            message.setContent("<h2 style='color:red'>恭喜您已注册成功,用户名为:"+user.getUsername()+"。</h2>", 
                    "text/html;charset=UTF-8");//设置邮件的具体内容

            //5、发送邮件------在网页上点击发送按钮
            ts.sendMessage(message, message.getAllRecipients());

            //6、关闭连接对象,即关闭服务器上的连接资源
            ts.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
java 复制代码
public class User {
    private String username;
    private String password;
    private String mailAddress;

    public User(String username, String password, String mailAddress) {
        this.username = username;
        this.password = password;
        this.mailAddress = mailAddress;
    }

    public User() {
    }

    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 getMailAddress() {
        return mailAddress;
    }

    public void setMailAddress(String mailAddress) {
        this.mailAddress = mailAddress;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", mailAddress='" + mailAddress + '\'' +
                '}';
    }
}
相关推荐
QCoding1 小时前
Java转AI第三课:Spring AI如何把100行HTTP代码缩减到10行?
java·人工智能
振宇i1 小时前
Java集成openfeign远程RPC调用教程
java·rpc·openfeign
wear工程师1 小时前
volatile 这题别只答「可见性」:面试官真正想听的是这条 happens-before
java·jvm
王九思1 小时前
对称加密与非对称加密详解
java·网络·数据库
米尔的可达鸭1 小时前
深入操作系统 Socket 底层:EPOLLOUT 可写事件管理 + 非阻塞异步
开发语言·网络·数据结构·经验分享·websocket·网络协议
SimonKing2 小时前
Spring Boot 4.0 + gRPC 极简集成:4步搞定,比REST还丝滑
java·后端·程序员
前端进阶之旅2 小时前
Next.js 16.3 新特性全解析 AI 驱动开发与 Instant Navigations 实战指南
开发语言·javascript·人工智能
C++、Java和Python的菜鸟2 小时前
第3章 后端Web基础 (Maven)
java
小小编程路2 小时前
Java super 关键字详解:用法、场景与常见误区
java·开发语言