Java基础的邮件收发

Java实现发送纯文本、附带图片、附件的邮件,使用JavaWeb实现邮件的发送。

Java发送邮件

传输协议

发送邮件:SMTP协议
接收邮件:POP3协议

我们通常把处理用户 smtp请求(邮件发送请求)的服务器称之为:SMTP服务器(邮件发送服务器)。
对应的,把处理用户 pop3请求的(邮件接收请求)的服务器称之为:POP3服务器(邮件接收请求)。

邮件收发原理

1583049379801.png

注意:有可能你的收件人,发件人地址等信息都填对了,控制台也打印了正确的信息,但是收件箱就是没有收到相应的邮件,有可能在【垃圾箱】中!
解决方法:重复的邮件内容不要多次发送,或者更换收件箱试试!

准备工作

QQ邮箱为例学习

首先要确保QQ邮箱开启了:POP3/SMTP服务

1583047319301.png

1583047386039.png

开启完毕后,会获得授权码,先保存下来。
新建一个 普通的Java项目。
使用Java发送E-mail十分简单,但是首先你应该准备 JavaMail API 和 Java Activation Framework。

发送邮件所需的依赖:

<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
<dependency>
    <groupId>com.sun.activation</groupId>
    <artifactId>javax.activation</artifactId>
    <version>1.2.0</version>
</dependency>

纯文本邮件

发送纯文本邮件,没有上传附件、图片、音频功能。
发送邮件需要的四个核心对象!

  • Session
  • Transport
  • Message
  • Store

1583047684276.png

1583050327963.png

代码:

package com.rainszj.mail;

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 {

    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 对象
        // QQ才有,其他邮箱不用
        Session session = Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 收件人邮箱用户名、授权码
                return new PasswordAuthentication("[email protected]", "授权码");
            }
        });

        // 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
        session.setDebug(true);
        // 2、通过session得到 transport对象
        Transport transport = session.getTransport();
        // 3、使用邮箱的用户名和授权码连上邮件服务器
        transport.connect("smtp.qq.com", "[email protected]", "授权码");
        // 4、创建邮件
        // 创建邮件对象,【注意需要传递 Session】
        MimeMessage message = new MimeMessage(session);
        // 指明邮件的发件人
        message.setFrom(new InternetAddress("[email protected]"));
        // 指明邮件的收件人,现在发件人和收件人是一样的
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]"));
        // 邮件的主题
        message.setSubject("一封简单的邮件!");
        // 邮件的文本内容
        message.setContent("<h1 style='color: red;'>你好</h1>", "text/html;charset=utf-8");
        // 5、发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        // 6、关闭连接
        transport.close();
    }
}

带图片的邮件

package com.rainszj.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 SendMail {

    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 对象

        // QQ才有,其他邮箱不用
        Session session = Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 收件人邮箱用户名、授权码
                return new PasswordAuthentication("收件人的QQ邮箱", "授权码");
            }
        });
		//==================================
		
        // 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
        session.setDebug(true);

        // 2、通过session得到 transport对象
        Transport transport = session.getTransport();

        // 3、使用邮箱的用户名和授权码连上邮件服务器
        transport.connect("smtp.qq.com", "发件人的QQ邮箱", "授权码");

        // 4、创建邮件
        // 创建邮件对象,【注意需要传递 Session】
        MimeMessage message = new MimeMessage(session);
        // 指明邮件的发件人
        message.setFrom(new InternetAddress("发件人的QQ邮箱"));
        // 指明邮件的收件人,现在发件人和收件人是一样的
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人的QQ邮箱"));

        message.setSubject("带图片的一封信!");
        
		//==================================
        // 准备图片数据
        MimeBodyPart image = new MimeBodyPart();
        // 图片需要经过数据处理   DataHandler
        DataHandler dh = new DataHandler(new FileDataSource("图片的路径"));
        // 在我们的Body中放入这个处理了的图片数据
        image.setDataHandler(dh);
        // 给图片设置一个ID,后面要用
        image.setContentID("favicon.png");

        // 准备正文数据
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("这是一段带图片<img src='cid:favicon.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、发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        // 6、关闭连接
        transport.close();

    }
}

cid:

1583051435872.png

通过拼装而成:
1583051763555.png

MimeMultipart 中的 subtype 默认是:mixed;

1583051391968.png

带附件的邮件

package com.rainszj.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;

/**
 * 发送邮件
 */
public class SendMail {

    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 对象

        // QQ才有,其他邮箱不用
        Session session = Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                // 收件人邮箱用户名、授权码
                return new PasswordAuthentication("收件人的邮箱", "授权码");
            }
        });
        //==================================================
        // 开启 Session 的 debug模式,这样就可以看到程序发送 Email的状态
        session.setDebug(true);

        // 2、通过session得到 transport对象
        Transport transport = session.getTransport();
        // 3、使用邮箱的用户名和授权码连上邮件服务器
        transport.connect("smtp.qq.com", "发件人的邮箱", "授权码");
        // 4、创建邮件
        // 创建邮件对象,【注意需要传递 Session】
        MimeMessage message = writeMail(session);
        // 5、发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        // 6、关闭连接
        transport.close();

    }


    private static MimeMessage writeMail(Session session) throws Exception {
        // 一封邮件
        MimeMessage message = new MimeMessage(session);
        // 指明邮件的发件人
        message.setFrom(new InternetAddress("发件人的邮箱"));
        // 主题
        message.setSubject("带图片和附件的一封信!");
        // 指明邮件的收件人,现在发件人和收件人是一样的
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人的邮箱"));

        /*
            编写邮件内容:
                1. 文本
                2. 图片
                3. 附件
         */
        //==================================================
        // 准备图片数据
        MimeBodyPart image = new MimeBodyPart();
        // 图片需要经过数据处理   DataHandler
        DataHandler dh = new DataHandler(new FileDataSource("图片的路径"));
        // 在我们的Body中放入这个处理了的图片数据
        image.setDataHandler(dh);
        // 给图片设置一个ID,后面要用
        image.setContentID("favicon.png");

        // 文本
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("这是一段带图片<img src='cid:favicon.png'/>的正文", "text/html;charset=utf-8");

        // 附件
        MimeBodyPart attachment = new MimeBodyPart();
        attachment.setDataHandler(new DataHandler(new FileDataSource("附件的路径")));
        attachment.setFileName("hello.properties"); // 设置附件的名字

        MimeBodyPart attachment2 = new MimeBodyPart();
        attachment2.setDataHandler(new DataHandler(new FileDataSource("附件的路径")));
        attachment2.setFileName("1.txt"); // 设置附件的名字

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

        // 进行拼装
        // 拼装文本和图片
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text);
        mm.addBodyPart(image);
        mm.setSubType("related");

        MimeBodyPart contentText = new MimeBodyPart();
        contentText.setContent(mm,"text/html;charset=utf-8");

        // 拼装附件
        MimeMultipart allFile = new MimeMultipart();
        allFile.addBodyPart(contentText);
        allFile.addBodyPart(attachment);
        allFile.addBodyPart(attachment2);
        allFile.setSubType("mixed");

        // 设置到消息中,保存修改
        message.setContent(allFile,"text/html;charset=utf-8");
        message.saveChanges();

        return message;
    }
}

JavaWeb实现邮件发送

新建一个JavaWeb项目

依赖

<!--javax.mail-->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
<dependency>
    <groupId>com.sun.activation</groupId>
    <artifactId>javax.activation</artifactId>
    <version>1.2.0</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

注意事项:ClassNotFound,有可能是lib目录没有生成成功!
1583062103161.png

添加方法:
1583062207266.png

发送邮件的表单:

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

<form action="${pageContext.request.contextPath}/registerServlet.do" method="post">
    <label>用户名:</label>
    <input type="text" name="username">
    <br/>
    <label>密码:</label>
    <input type="password" name="password">
    <br/>
    <label>邮箱:</label>
    <input type="text" name="email">
    <input type="submit" value="提交">
</form>
</body>
</html>

RegisterServlet

@WebServlet("/registerServlet.do")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");

        System.out.println(username);
        System.out.println(password);
        System.out.println(email);

        User user = new User(username, password, email);

        // 使用多线程来专门发送邮件,防止出现耗时,和网站注册人数过多的情况【异步任务】
        SendEmail sendEmail = new SendEmail(user);
        // 启动线程
        sendEmail.start();

        request.setAttribute("message", "注册成功,我们已经发送一封带有注册信息的邮件,请注意查收!");
        request.getRequestDispatcher("info.jsp").forward(request,response);


    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

发送邮件的线程:

package com.rainszj.utils;

import com.rainszj.pojo.User;
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;

public class SendEmail extends Thread {

    // 邮箱用户名
    private String username = "[email protected]";
    // 邮箱密码
    private String pasword = "授权码";
    // 发送邮件的服务器地址
    private String host = "smtp.qq.com";
    // 发件人的邮箱
    private String from = "[email protected]";

    private User user;

    public SendEmail(User user) {
        this.user = user;
    }

    @Override
    public void run() {
        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 = null;
        try {
            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() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    // 收件人邮箱用户名、授权码
                    return new PasswordAuthentication("[email protected]", "授权码");
                }
            });
            //========================================

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

            // 2、通过session得到 transport对象
            Transport transport = session.getTransport();
            // 3、使用邮箱的用户名和授权码连上邮件服务器
            transport.connect(host, username, pasword);
            // 4、创建邮件
            // 创建邮件对象,【注意需要传递 Session】
            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();
            // 5、发送邮件
            transport.sendMessage(message, message.getAllRecipients());
            // 6、关闭连接
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

info.jsp

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

${message}
</body>
</html>

注:在真实的开发中,我们不会这么做,通过SpringBoot可以轻易的实现邮件的发送!

猜你喜欢

转载自www.cnblogs.com/rainszj/p/12795903.html