Java邮件开发介绍

为什么要学习javamail开发

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

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

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

学习目标

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

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

邮件开发过程中的一些常见问题:

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

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

邮件服务器和电子邮箱

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

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

  • SMTP协议
    用户连上邮件服务器后,要想给它发送一封电子邮件,需要遵循一定的通迅规则,SMTP协议就是用于定义这种通讯规则的。因而,通常我们也把处理用户smtp请求(邮件发送请求)的邮件服务器称之为SMTP服务器(邮件发送服务器)。(SMTP服务器工作在25号端口上)
  • POP3协议
    同样,用户若想从邮件服务器管理的电子邮箱中接收一封电子邮件的话,他连上邮件服务器后,也需要遵循一定的通迅格式,POP3协议用于定义这种通讯格式。因而,通常我们也把处理用户pop3请求(邮件接收请求)的邮件服务器称之为POP3服务器(邮件接收服务器)。(POP3服务器工作在110号端口上)

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

通过一张图来说明一封邮件的发送和接收过程,如下图所示:

简单说一下这个邮件收发过程:

  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())); }}
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

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

使用SMTP协议发送邮件

SMTP协议讲解

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

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

    • echo hello
  • 使用auth login命令登录到smtp服务器,登录使用的用户名和密码必须是经过base64编码后的用户名和密码,例如:
    1. 输入命令:auth login
    2. 输入使用base64加密过后的用户名:eWVyZW55dW+1sFuMTAwMDE=
    3. 输入使用base64加密过后的密码:MTAwMDF5ZXJl+2sbnl1YW4=
  • 指明邮件的发件人和收件人
    • mail from: <yerenyuan10001@163.com>
    • rcpt to: <i_beautifulman@sina.com>
  • 编写要发送的邮件内容,邮件的编写格式是有一定的规则的,必须符合RFC822文档规范,RFC822文档规定了如何编写一封简单的邮件,一封格式良好的邮件应该包含邮件头和邮件的主体内容,并且邮件头和邮件体两者之间要使用空行分隔
    邮件头使用下面的三个字段来指明:

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

    邮件体:即邮件内容。
    邮件的内容包含了这些信息之后才是一封格式良好的邮件。

    1. 输入data命令:

      data

    2. 编写邮件内容

      from: <yerenyuan10001@163.com>    ——邮件头
      to: <i_beautifulman@sina.com>      ——邮件头
      subject: hello           ——邮件头
      <空行>
      hello world           ——邮件的具体内容

    提示:可利用RFC822文档漏洞发送假冒邮件

  • 输入一个.告诉邮件服务器邮件内容已经写完了。
    • .
  • 输入quit命令断开与邮件服务器的连接。
    • quit

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

使用SMTP协议手工发送邮件

在对SMTP协议有一定的了解之后,我们就可以使用SMTP协议来发送邮件了。下面演示一下使用telnet客户端连接上163的邮件服务器然后发一封Email到sina的邮箱中去。
为了能够对SMTP协议有一个直观的认识,这里我们不借助任何第三方邮件客户端工具,而是使用最原始的的telnet客户端来完成邮件的发送过程,telnet是一个windows自带的网络客户端程序,通过它可以连接上互联网上面的任意一台主机
大概有人是第一次使用telnet客户端的工具,我们试着使用telnet客户端连接sina的smtp服务器,发现会出现’telnet’ 不是内部或外部命令,也不是可运行的程序这样乱七八糟的东西,如下图所示:

要解决该问题,可以参见我的笔记win7操作系统下使用telnet客户端。
好了,现在我们使用telnet客户端连接到网易的smtp服务器上,如下图所示:

通过telnet客户端发Email,如下图所示:

这时我们发现会报一个错误:

554 DT:SPM

SMTP服务器会给我们一个提示,让我们去找这个页面:http://mail.163.com/help/help_spam_16.htm?ip=36.110.119.29&hostid=smtp12&time=1474462974,我们进入该页面之后发现

退信代码说明:
554 DT:SPM 发送的邮件内容包含了未被许可的信息,或被系统识别为垃圾邮件。请检查是否有用户发送病毒或者垃圾邮件;

这说明我们使用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加密。

    • user username——登录邮箱的用户名
    • pass password——登录邮箱使用的密码
  • 使用retr命令收取邮件。
    • retr 数字:收取邮件,如retr 1表示收取邮箱当中的第一封邮件,这是POP3协议里面最重要的一个命令。
      在使用retr命令收取邮件之前,可以使用如下的两个命令查看一下邮箱里面的邮件的一些相关信息。

      • stat:返回邮箱里面的邮件数量以及邮件占用的空间大小信息(可以看到有几封电子邮件,总共占用多少个字节)
      • list:返回某一封邮件的统计信息(可以看到每封电子邮件分别占用多少个字节)
  • 邮件收取完成之后使用quit命令断开与POP3服务器的连接。
    • 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来进行邮件发送。

(function () {(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(′\n′).length;var(this).text().split('\n').length;var numbering = $('

  • ').addClass('pre-numbering').hide(); (this).addClass(′has−numbering′).parent().append((this).addClass('has-numbering').parent().append(numbering); for (i = 1; i

电子邮件收发原理和JavaMail开发相关推荐

  1. 计算机网络原理和OSI模型与TCP模型

    计算机网络原理和OSI模型与TCP模型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.计算机网络的概述 1.计算机网络的定义 计算机网络是一组自治计算机的互连的集合 2.计算机 ...

  2. AES加密原理和AOE工程实践

    AES加密原理和AOE工程实践 在AI业务的开发的过程中,我们常常需要对模型文件进行加密. 我们从以下几个方面来说一说AES的加密原理以及AOE里的工程实践. 常见的加密算法 AOE对模型加密需求的思 ...

  3. mvc原理和mvc模式的优缺点

    mvc原理和mvc模式的优缺点 一.mvc原理    mvc是一种程序开发设计模式,它实现了显示模块与功能模块的分离.提高了程序的可维护性.可移植性.可扩展性与可重用性,降低了程序的开发难度.它主要分 ...

  4. 学习 koa 源码的整体架构,浅析koa洋葱模型原理和co原理

    前言 这是学习源码整体架构系列第七篇.整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现.本篇文章学习的是实际仓库的代码. 学习源码整体 ...

  5. C#毕业设计——基于C#+asp.net+cs的电子邮件收发系统设计与实现(毕业论文+程序源码)——电子邮件收发系统

    基于C#+asp.net+cs的电子邮件收发系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+cs的电子邮件收发系统设计与实现,文章末尾附有本毕业设计的论文和源码下 ...

  6. web应用原理和tomact服务器介绍

    web应用原理和tomact服务器介绍 HTTP协议 工作原理 HTTP 消息结构 客户端请求消息 服务器响应消息 HTTP方法 Web应用原理 静态页面 动态页面 web服务器 协议 www tom ...

  7. c语言混沌系统,请熟悉混沌原理和c高手帮个忙 (转)

    请熟悉混沌原理和c高手帮个忙 (转)[@more@] 小弟毕业设计做的是"混沌同步原理在保密通信中的应用及开发",由于功底不够,现在在c语言编程上遇到了问题,不解决的话便难以往下作 ...

  8. SM4分组加密算法原理和c语言实现

    一.前言 在之前的文章中介绍了<SM3国密杂凑值算法的原理和c语言实现>,这篇文章主要是用c语言撸一个SM4分组加密算法. 随着信息安全的普及以及等级保护等安全政策落地,国密算法越来越频繁 ...

  9. Mybatis插件原理和PageHelper结合实战分页插件(七)

    今天和大家分享下mybatis的一个分页插件PageHelper,在讲解PageHelper之前我们需要先了解下mybatis的插件原理.PageHelper 的官方网站:https://github ...

  10. HBase学习指南之HBase原理和Shell使用

    HBase学习指南之HBase原理和Shell使用 参考资料: 1.https://www.cnblogs.com/nexiyi/p/hbase_shell.html,hbase shell 转载于: ...

最新文章

  1. CSS3支持IE6, 7, and 8的边框属性
  2. 用 Python 对比两个目录下的内容,并生成 Json 文件
  3. signature=54cb1c123491dc1a268a21f3502cccfc,Modelling information routing with noninterference
  4. 如何选购工业级光模块
  5. Ubuntu搜狗输入法安装
  6. Tomcat系列(6)——Tomcat处理一个HTTP请求的过程
  7. AMIO编辑器开发(四):五一劳动节的编程较量,C++语言的设计模式
  8. DALSA相机开发记录(01)
  9. 面向对象和面向过程思想 oc
  10. jQuery ajax error函数(交互错误信息的获取)
  11. catia中的螺旋伞齿轮画法,基于CATIA的螺旋锥齿轮参数化建模方法研究
  12. 计算机怎么合并单元格并保存内容,怎么合并单元格并保留所有数据
  13. linux 安装pkg文件,Linux的pkg-config命令
  14. Android音视频开发之ExoPlayer(一):快速入门ExoPlayer
  15. CompletableFuture学习
  16. 基于PLC的实验室设备远程监控方案
  17. 关于error C2059: 语法错误:“类型”,初学者的一点收获
  18. 源码时代UI干货分享|Axure基础教程
  19. 20个有用的iOS图标和应用模板资源
  20. AnnaAraslanova/FBNet 程序分析

热门文章

  1. android 实现页面跳转代码,Android 实现页面跳转
  2. 清理迅雷系列软件数据记录【破坏性】
  3. 学习爬虫第二天:继续爬公司内部的通讯录
  4. qs.stringify()详情
  5. cad快看_CAD快速看图可以图纸对比吗?可以!
  6. CAD迷你看图 for Mac(强大的cad看图软件)
  7. jQuery插件的简单使用及制作
  8. 免费中文版Adobe Acrobat Reader DC PDF文件阅读软件
  9. iOS和安卓合并二维码
  10. 计算机怎样双面打印,电脑双面打印机怎么打印双面_电脑如何设置自动双面打印-win7之家...