大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: J&C 修改讲义

发送Email

Email并不能在用户之间直接传递,而是依赖于邮件的:

  • 发送服务器(如下图:smtp.163.com)
  • 接收服务器(如下图:pop.qq.com)

  1. 发送方(sender)将email推送给邮件发送服务器。这一过程可以由用户登录邮箱网站完成,或使用其他邮箱软件(如outlook)推送
  2. 163.com按邮件收件人地址将email推送到qq.com服务器
  3. 收件方(receiver)从服务器拉取自己的email

上述3个过程,1和2都是推送,使用SMTP(Simple Mail Transfer Protocol)协议;3是拉取,使用的是POP3协议。

我们开发中所谓的“发送email”其实只关注第1个阶段,即把邮件内容推送到


SMTP服务器

练习时推荐使用网易免费邮箱

首先需要自己去申请一个账号,我为了方便教学,已经弄好了:

  • 用户名:feige_20200214
  • 密码:yz17bang
真实可用,^_^,yz17bang为“客户端授权密码”,即通过程序推送email使用的密码(如果要从网易邮箱网页登录,需使用登录密码:yuanzhan17bang)

邮件服务商会提供Host(服务器地址)和Port(连接用端口号),

  • host:smtp.163.com
  • port:25 (如果使用ssl加密方式,403)

通过这些信息,我们就能连接上网易的SMTP服务器,推送email。


Email内容

一般包括:

  • 发件人(From):主要内容为email地址
  • 收件人(To)::可以是一个或多个,还可以有抄送等,但开发中用得
  • 标题(Subject):
  • 正文(Body):
    正文可以为HTML格式。
  • 附件(Attachment)

类库

你不用担心不知道SMTP协议究竟是怎么约定的,不知道怎么建立连接如何推送……

我们只需要利用一些封装得很好的类库,就可以轻松的实现email的发送(体会:封装的作用)

故障

email的发送并不总是能够成功到达的,就像我们寄出去的信一样:我们能够控制的是把信交给邮局这一段,之后我们就没法控制了。

一般来说,以下情况我们能够收到异常信息:

  • 和SMTP服务器没有连接成功:找不到smtp服务器;端口、用户名或密码不对;连接超时……
  • SMTP推送到POP服务器没有成功:收件人地址错误;POP服务器拒收……

但以下情况会收到异常信息:

  • 收件人拒收:被判定为垃圾邮件、拉取失败故障……

所以实际开发中我们要注意:

  1. 记录email发送异常日志并定时检查
  2. 密切关注发送邮箱的退件信息等

发送短信

因为没有标题正文啥的,比发送email还要简单!

获取 SecretID 和 SecretKey

只需要使用服务商提供的SDK(各种语言都有),按文档调用相关的API就OK了。

PS:SDK(Software Development Kit,软件开发工具包),可以简单理解为API的集合



配置文件

项目运行所需的有些信息:

  • 是机密的,不应该被暴露的,比如发送Email、连接数据库等需要的账号/密码
  • 是需要在运行的过程中动态调整的,比如:缓存的时间

这些信息就不宜放在代码中,而是可以放置在所谓的“配置文件”中

配置文件的格式一般可以是(演示):

一般来说,Java和C#都会有基本的类库方法,可以很方便的读取配置文件中的信息。且

  • 项目只在启动时读取一次就将其内容缓存(高性能)
  • 但在配置上面所做的更改不需要重启项目就可以立即生效


日志log

email或短信发送失败(以及其他各种异常信息)一般都要通过log记录,以便维护。

出于性能的考虑,我们通常使用(使用了大量性能优化技术的)成熟的第三方组件进行日志记录。

其中最负盛名的就是log4(历史悠久,稳如老狗):C#的log4.net和Java的log4j,其核心对象都是logger
Logger logger = LogManager.getLogger("17bang");

logger.trace("this is a trace message……");
logger.debug("this is a debug message……");
logger.info("this is a info message……");
logger.warn("this is a warn message……");
logger.error("this is a error message……");
logger.fatal("this is a fatal message……");
其中:
  • 17bang是logger的name
  • trace()等是logger的方法,但代表的是logger的level

他们都依赖于其配置文件,这两行的代码意思是:如果配置文件中配置了17bang的logger,且标记为trace级别,就记录内容this is a trace message……

配置文件一般是xml格式,包含的logger节点如下所示:

<Loggers>
	<Logger name="17bang" level="DEBUG">
		<AppenderRef ref="File" />
		<AppenderRef ref="Console" />
	</Logger> 
level按级别从小到大是:TRACE<DEBUG<INFO<WARN<ERROR<FATAL<OFF

在配置文件中定义的是级别的“下限”,比如:level="DEBUG",就只会输出debug以上的内容,不会输出debug以下trace的内容。

logger依赖于Appender,Appender指定log输出的方式:

<Appenders>
	<Console name="Console" target="SYSTEM_OUT">
		<PatternLayout
			pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
	</Console>
	<File name="File" fileName="c:/log/app.log">
		<PatternLayout
			pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
	</File>
</Appenders>
首先是节点名称,只能是Console/File/Writer等,指示了日志输出到控制台/文件/自定义流……

name供logger引用:<AppenderRef ref="File" />

Console要指定target,File要指定文件路径

然后里面的PatternLayout,通过pattern指定具体的输出内容:

  • %d:日期时间(datetime),后面的{yyyy-MM-dd hh:mm:ss} 表明年月日小时分钟秒等日期格式
  • %t:所在线程(thread)
  • %-5level:日志等级
  • %logger{36}:logger名称
  • %msg:日志内容
  • %n:换行
  • ……

演示和其他说明:略


作业

  1. 逐行同步/异步并发的读取之前的newEmail.txt文件,利用代码将一封HTML格式的邮件发送到其包含的email邮箱地址中
  2. 并将发送成功/失败的信息通过log4记录到文件日志
学习笔记
源栈学历
今天学习不努力,明天努力找工作

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 J&C 中继续学习:

下一课: 已经是最后一课了……

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码