Java Web基础入门第九十五讲 JavaMail开发——邮件的发送与接收原理

Java Web基础入门 专栏收录该内容
115 篇文章 22 订阅

Java邮件开发介绍

为什么要学习JavaMail开发?

现在很多WEB应用在开发时都需要集成邮件发送功能,例如:

  • 给新注册的用户自动发送一封包含其注册信息的欢迎E-Mail;
  • 给过生日的注册会员自动发送一封表示祝贺的E-Mail;
  • 将网站的最新活动信息通过E-Mail发送给所有的注册会员;
  • 等等…

这些功能的实现都需要软件开发人员在开发WEB应用中编写相应的邮件处理程序。

学习目标

学习JavaMail主要包括两部分:生成邮件和发送接收邮件。学习JavaMail开发之后可以达成的效果:

  • 可以编写程序代码生成一封带内嵌图片的邮件;
  • 可以编写程序生成一封即带附件又带图片的复杂邮件;
  • 可以编写Java邮件发送程序发送邮件;
  • 可以实现类似sina、sohu等的WEB邮件发送程序。

当然了,我们会在JavaMail邮件开发过程中遇到以下一些常见问题:

  • 中文名的邮件附件的乱码问题;
  • Tomcat中JavaMail支持与冲突问题;
  • 如何实现邮件群发。

邮件开发涉及到的一些基本概念

邮件服务器和电子邮箱

何谓邮件服务器?要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器。例如现在Internet上有很多提供邮件服务的厂商,如sina、sohu、163等等他们都有自己的邮件服务器。这些服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
什么是电子邮箱呢?电子邮箱(E-mail地址)的获得需要在邮件服务器上进行申请,确切地说,电子邮箱其实就是用户在邮件服务器上申请的一个帐户。用户在邮件服务器上申请了一个帐号后,邮件服务器就会为这个帐号分配一定的空间,用户从而可以使用这个帐号以及空间,发送电子邮件和保存别人发送过来的电子邮件。

邮件传输协议和邮件服务器类型

在这里插入图片描述
在这里插入图片描述

电子邮件的发送和接收过程

通过一张图来说明一封邮件的发送和接收过程,如下图所示:
在这里插入图片描述
简单说一下这个邮件收发过程:

  1. yerenyuan10001@163.com用户写好一封Email之后,发送到163的SMTP服务器。对应于上图的步骤①;
  2. 163的SMTP服务器开始处理yerenyuan10001@163.com用户的请求,它会根据收件人的地址判断,当前收件人是不是自己管辖的用户,如果是,就直接将Email存放到为该收件人分配的邮箱空间当中。163的SMTP服务器判断收件人地址发现,这一封Email的收件人i_beautifulman@sina.com是sina的邮件服务器管理的,于是又将Email转发给sina的SMTP服务器。对应于上图的步骤②;
  3. sina的SMTP服务器开始处理163的SMTP服务器发送过来的Email,sina的SMTP服务器根据收件人的地址判断,发现收件人是自己管辖的用户,于是就直接将Email存放到为i_beautifulman@sina.com用户分配的邮箱空间当中。对应于上图的步骤③;
  4. yerenyuan10001@163.com用户将邮件发出去之后,就通知i_beautifulman@sina.com用户去收取。i_beautifulman@sina.com用户于是就连接上sina的POP3服务器收取邮件。对应于上图的步骤④;
  5. POP3服务器从i_beautifulman@sina.com用户的邮箱空间当中取出Email。对应于步骤⑤;
  6. POP3服务器将取出来的Email发给i_beautifulman@sina.com用户。对应于步骤⑥。

手工演示电子邮件的发送(实验失败)

为了增强学习的趣味性和调动大家学习的热情,我先通过手工方式来发送和接收一封邮件,我在163和sina上分别开设了一个邮箱账号,我想用163的邮箱向sina的邮箱中发送一封邮件,这个邮件发送过程是怎样的呢?先用画图的方式简要描述一下(参见上图),我们要发送和接收邮件,首先要知道163和sina的邮件服务器地址,邮件服务器帮我们干什么呢?帮我们把邮件发出去,帮我们把邮件接收进来,为我们提供取邮件的服务。
然后,我们就要思考一个问题:是直接把邮件发给sina的邮件服务器,还是经过163的服务器发给sina呢?我们分别要连接它们的什么服务器呢?很显然,是经过163的邮件服务器发送给sina的邮件服务器。

准备实验环境

首先,提前在163和sina上注册一个免费帐号。然后,获取SMTP和POP3服务器的名称,163或sina会在其帮助中心里提示管理当前注册帐号的邮件服务器的主机名。

  • 网易163免费邮箱相关服务器信息
    在这里插入图片描述
  • sina免费邮箱相关服务器信息
    在这里插入图片描述

接着,编写Base64编码程序对用户名和密码进行编码,这样的程序代码为:

public class Base64Util {

    public static void main(String[] args) throws IOException {
        System.out.print("请输入用户名:");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String userName = in.readLine();
        System.out.print("请输入密码:");
        String password = in.readLine();
        BASE64Encoder encoder = new BASE64Encoder();
        System.out.println("编码后的用户名为:" 
                + encoder.encode(userName.getBytes()));
        System.out.println("编码后的密码为:" 
                + encoder.encode(password.getBytes())); 

    }

}

准备好实验环境之后,那我们就手工使用SMTP协议发送电子邮件。

使用SMTP协议发送邮件

SMTP协议讲解

使用SMTP协议发送邮件给邮件服务器时规定了要做以下几件事:

  • 使用ehlo命令和连接上的SMTP服务器打声招呼,例如ehlo hello

  • 使用auth login命令登录到SMTP服务器,登录使用的用户名和密码必须是经过Base64编码后的用户名和密码,例如,
    在这里插入图片描述

  • 指明邮件的发件人和收件人。例如,
    在这里插入图片描述

  • 编写要发送的邮件内容,邮件的编写格式是有一定的规则的,必须符合RFC822文档规范,RFC822文档规定了如何编写一封简单的邮件,一封格式良好的邮件应该包含邮件头和邮件的主体内容,并且邮件头和邮件体两者之间要使用空行分隔。邮件头使用下面的三个字段来指明:

    • from字段用于指明邮件的发送人;
    • to字段用于指明邮件的收件人;
    • subject字段用于指明邮件的主题。

    邮件体即邮件内容。邮件的内容包含了这些信息之后才是一封格式良好的邮件。
    在这里插入图片描述
    温馨提示:可利用RFC822文档漏洞发送假冒邮件

  • 输入一个.告诉邮件服务器邮件内容已经写完了;

  • 输入quit命令断开与邮件服务器的连接。

以上的6个步骤就是SMTP协议规定的发送一封Email必须要做的事情。

使用SMTP协议手工发送邮件

在对SMTP协议有一定的了解之后,我们就可以使用SMTP协议来发送邮件了。下面演示一下使用telnet客户端连接上163的邮件服务器然后发一封Email到sina的邮箱中去。
为了能够对SMTP协议有一个直观的认识,这里我们不借助任何第三方邮件客户端工具,而是使用最原始的telnet客户端来完成邮件的发送过程,telnet是一个Windows自带的网络客户端程序,通过它可以连接上互联网上面的任意一台主机。大概有人是第一次使用telnet客户端的工具,我们试着使用telnet客户端连接sina的SMTP服务器,发现会出现telnet不是内部或外部命令,也不是可运行的程序这样乱七八糟的东西,如下图所示:
在这里插入图片描述
要解决该问题,可以参见我的笔记《Windows操作系统下使用telnet客户端》
好了,现在我们使用telnet客户端连接到网易的SMTP服务器上,如下图所示:
在这里插入图片描述
然后,通过telnet客户端发Email,如下图所示:
在这里插入图片描述
这时我们发现会报一个错误:
在这里插入图片描述
SMTP服务器会给我们一个提示,让我们去找这个页面:http://mail.163.com/help/help_spam_16.htm?ip=121.32.196.208&hostid=smtp11&time=1560670813,我们进入该页面之后发现
在这里插入图片描述
这说明我们使用telnet客户端连接上163的邮件服务器然后发一封Email,163的SMTP服务器认为该邮件的内容包含了未被许可的信息,或被其识别为垃圾邮件,所以将该邮件退回。
接着我想,既然使用telnet客户端连接上163的邮件服务器然后发一封Email到sina的邮箱中去失败了,那么试试使用telnet客户端连接上163的邮件服务器然后发一封Email到qq的邮箱中去,结果依然报相同的错误:
在这里插入图片描述
接着,我试着使用telnet客户端连接上sina的邮件服务器然后发一封Email到163的邮箱中去,结果验证都没通过:
在这里插入图片描述
再接着,我试着使用telnet客户端连接上qq的邮件服务器然后发一封Email到163的邮箱中去,结果也是连登录验证都没通过。
在这里插入图片描述
此刻,我已经疯了!!!所以,使用SMTP协议手工发送一封电子邮件的实验失败!

手工演示电子邮件的接收

使用POP3协议接收邮件

POP3协议讲解

POP3协议规定了收取邮件时要做以下几件事:

  • 输入用户名和密码登录到POP3服务器,用户名和密码不需要经过Base64加密;
    在这里插入图片描述
  • 使用retr命令收取邮件;
    在这里插入图片描述
  • 邮件收取完成之后使用quit命令断开与POP3服务器的连接。

使用POP3协议手工接收邮件

收取邮件我们也不借助任何第三方客户端工具,而是使用telnet客户端连接到POP3服务器进行收取。例如,现在我的163邮箱当中有这样的一封邮件,如下图所示:
在这里插入图片描述
现在我们不用使用foxmail或者outLook这样的客户端工具去收取,而是使用telnet客户端连接到163的POP3服务器去手工收取。
使用telnet连接上163的POP3服务器,使用命令:telnet pop.163.com 110,如下图所示:
在这里插入图片描述
接着根据POP3协议规定的邮件收取步骤来收取邮件。如下图所示:
在这里插入图片描述
可以看到,我们使用POP3协议纯手工从163的POP3服务器当中收取回来了一封Email,Email里面的内容都经过了Base64编码处理。这就是使用POP3协议收取邮件的过程。
以上就是邮件的发送与接收原理的相关内容,这一篇文章主要是介绍邮件发送和接收过程中使用到的SMTP协议和POP3协议,没有涉及到太多代码方面的东西,后面会具体介绍使用JavaMail来进行邮件发送。

  • 6
    点赞
  • 2
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 猿与汪的秘密 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值