Java实现QQ邮件发送原理和实现

电子邮件

在网络中实现邮件发送和接收的功能,就必须要有专门的邮件服务器(使用SMTP协议)。我们发送一封邮件,先要经过各层路由,交换机,基站,然后存到该邮件服务器,(不同的邮件有不同的邮件服务器,比如网易的邮箱服务器,QQ的邮箱服务器),然后发送的邮箱服务器(使用POP3协议)。又通过基站发送到对应的服务器中,这个时候作为收件人会有邮件到达的提醒,在你打开邮件的过程就是从邮件服务器中读取数据的过程。
SMTP服务器地址:一般是smtp.xxx.com,比如smtp.163.com,smtp.qq.com,电子邮箱的获得需要在邮件服务器中去申请。

下面是实现过程

1.首先在QQ邮箱获取授权码

在这里插入图片描述
这里需要验证密保方式,短信令牌都可以,我已经获取了,就不再演示了。

2.获取两个jar包(从maven 仓库可以很方便获取)

1.mail.jar
2.activition.jar

JavaMail是sun公司为方便java开发 人员在应用程序中实现邮件发送和接收功能而提供的一套标准开发包,它支持一些常用的邮件协议,比如SMTP,POP3,IMAP,MIME等,在开发中只需要调用相应的api就可以,无需关心底层的实现。
在编写程序中主要有这四个核心类:
在这里插入图片描述

3.代码实现(简单文本)

    public static void main(String[] args) throws GeneralSecurityException, MessagingException {

        //这是我的授权码:bgqyouievmjubjai
        Properties prop=new Properties();
        prop.setProperty("mail.host","smtp.qq.com");//设置qq邮件服务器
        prop.setProperty("mail.transport.protocol","smtp");//邮箱发送协议
        prop.setProperty("mail.stmp.auuuth","true");//需要验证用户名密码

        //设置SSL加密
        MailSSLSocketFactory sf=new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);  
        prop.put("mail.smtp.ssl.enable","true");
        prop.put("mail.smtp.ssl.socketFactory",sf);

        //1 创建定义整个应用程序所需环境信息的session 对象

        Session session=Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("415866969@qq.com","bgqyouievmjubjai");

            }
        });

        //开启debug模式,开启后会在控制台打印邮件发送过程中的参数信息,不开启则不显示
        session.setDebug(true);
        //2 通过session得到transport对象
        Transport ts = session.getTransport();

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

        //4 创建邮件,写邮件
        MimeMessage message=new MimeMessage(session);
        //指明发件人
        message.setFrom(new InternetAddress("415866969@qq.com"));
        //收件人,我这里是自己给自己发送
        message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("415866969@qq.com")});
        //邮件主题
        message.setSubject("只包含文本"); 
        //邮件内容
        message.setContent("你好你好啊,我是01","text/html;charset=UTF-8");

        //5 发送邮件
        ts.sendMessage(message,message.getAllRecipients());

        //6 关闭邮件
        ts.close();

    }

运行结果

"E:\Program Files\Java\jdk-14.0.1\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=64935:D:\Program Files\JetBrains\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\mail-java\out\production\mail-java;F:\IdeaProjects\mail-java\lib\mail-1.4.7.jar;F:\IdeaProjects\mail-java\lib\activation-1.1.1.jar com.ycm.test.Test
DEBUG: setDebug: JavaMail version 1.4.7
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.qq.com", port 465, isSSL true
220 newxmesmtplogicsvrszc9.qq.com XMail Esmtp QQ Mail Server.
DEBUG SMTP: connected to host "smtp.qq.com", port: 465

EHLO LAPTOP-RQ19S512
250-newxmesmtplogicsvrszc9.qq.com
250-PIPELINING
250-SIZE 73400320
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN
250-MAILCOMPRESS
250 8BITMIME
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "SIZE", arg "73400320"
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg ""
DEBUG SMTP: Found extension "MAILCOMPRESS", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM 
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
DEBUG SMTP: use8bit false
MAIL FROM:<415866969@qq.com>
250 OK.
RCPT TO:<415866969@qq.com>
250 OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   415866969@qq.com
DATA
354 End data with <CR><LF>.<CR><LF>.
From: 415866969@qq.com
To: 415866969@qq.com
Message-ID: <1652149987.0.1595824848890.JavaMail.41586@smtp.qq.com>
Subject: =?UTF-8?B?5Y+q5YyF5ZCr5paH5pys?=
MIME-Version: 1.0
Content-Type: text/html;charset=UTF-8
Content-Transfer-Encoding: base64

5L2g5aW95L2g5aW95ZWK77yM5oiR5pivMDE=
.
250 OK: queued as.
QUIT
221 Bye.

Process finished with exit code 0

在这里插入图片描述

下面是发送带图片的邮件,只需要修改几处就可以,只贴了代码

public static void main(String[] args) throws GeneralSecurityException, MessagingException{
        //这是我的授权码:bgqyouievmjubjai
        Properties prop=new Properties();
        prop.setProperty("mail.host","smtp.qq.com");//设置qq邮件服务器
        prop.setProperty("mail.transport.protocol","smtp");//邮箱发送协议
        prop.setProperty("mail.stmp.auuuth","true");//需要验证用户名密码

        //设置SSL加密
        MailSSLSocketFactory sf=new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        prop.put("mail.smtp.ssl.enable","true");
        prop.put("mail.smtp.ssl.socketFactory",sf);

        //1 创建定义整个应用程序所需环境信息的session 对象

        Session session=Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("415866969@qq.com","bgqyouievmjubjai");

            }
        });

        //开启debug模式
        session.setDebug(true);
        //2 通过session得到transport对象
        Transport ts = session.getTransport();

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

        //4 创建邮件,写邮件
        MimeMessage message=new MimeMessage(session);
        //指明发件人
        message.setFrom(new InternetAddress("415866969@qq.com"));
        //收件人,我这里是自己给自己发送
        message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("415866969@qq.com")});
        //邮件主题
        message.setSubject("包含图片的文件");

        //准备邮件数据

        //准备图片数据
        MimeBodyPart image=new MimeBodyPart();
        DataHandler dh=new DataHandler(new FileDataSource("F:\\IdeaProjects\\mail-java\\src\\logo.png"));
        image.setDataHandler(dh);
        image.setContentID("logo.png");

        //准备正文数据
        MimeBodyPart text=new MimeBodyPart();
        text.setContent("这是一封邮件带图片的<img src='cid:logo.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());

        //6 关闭邮件
        ts.close();
    }

下面在Java Web中实现邮件发送

前端是一个form表单,用于接收参数

<form action="/RegisterServlet.do" method="post">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    邮箱:<input type="text" name="email"> <br>
    <input type="submit" value="注册">
  </form>

servlet

public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        //接收参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");

        //封装成实体类
        User user=new User(username,password,email);

        SendMail send=new SendMail(user);
        send.start();

        request.setAttribute("message","注册成功");
        request.getRequestDispatcher("info.jsp").forward(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}

这个还有一个工具类,主要的功能就是发送邮件,通过接收前端传来的User对象封装数据。
需要指出的是,这个类的实例方法实现是用一个多线程来实现的,也就是说当点击发送邮件的时候,再开一个新的线程去执行,这样做的好处是可以优化用户体验,假设不用多线程来处理,当点击发送邮件,页面会停留在加载界面,直到文件发送成功。


/**
 * 在把发送邮件的任务再开一个线程去处理,
 * 避免当点击发送邮件的时候一直停留在网页等待的界面
 * 可以优化用户体验
 */
public class SendMail extends Thread {

    //要发送的邮箱
    private String from="415866969@qq.com";
    //收信的邮箱
    private String username="415866969@qq.com";
    //邮箱密码
    private String password="bgqyouievmjubjai";
    //发送邮件的服务器地址
    private String host="smtp.qq.com";

    private User user;

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

    @Override
    public void run() {

        try{
            //这是我的授权码:bgqyouievmjubjai
            Properties prop=new Properties();
            prop.setProperty("mail.host","smtp.qq.com");//设置qq邮件服务器
            prop.setProperty("mail.transport.protocol","smtp");//邮箱发送协议
            prop.setProperty("mail.stmp.auuuth","true");//需要验证用户名密码

            //设置SSL加密
            MailSSLSocketFactory sf=new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            prop.put("mail.smtp.ssl.enable","true");
            prop.put("mail.smtp.ssl.socketFactory",sf);

            //1 创建定义整个应用程序所需环境信息的session 对象

            Session session=Session.getDefaultInstance(prop, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("415866969@qq.com","bgqyouievmjubjai");

                }
            });

            //开启debug模式
            session.setDebug(true);
            //2 通过session得到transport对象
            Transport ts = session.getTransport();

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

            //4 创建邮件,写邮件
            MimeMessage message=new MimeMessage(session);
            //指明发件人
            message.setFrom(new InternetAddress(from));
            //收件人,我这里是自己给自己发送
            message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(user.getEmail())});
            //邮件主题
            message.setSubject("只包含文本");
            //邮件内容
            message.setContent("你好你好啊,我是01","text/html;charset=UTF-8");
            message.saveChanges();
            //5 发送邮件
            ts.sendMessage(message,message.getAllRecipients());

            //6 关闭邮件
            ts.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值