[TOC]
描述:最近正好在学邮件发信与激活的小程序开发,顺便把邮箱发信的基础知识理一理方便后续的开发工作以及安全相关的一些知识;
Q:什么是邮件服务器? 答:它可以类似于现实生活中的邮局投递用户的邮件,电子邮件是Intenet基本服务之一,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱,但是前提是需要在服务器上安装相应的邮件服务器应用; 使用电子邮件系统可以实现不受时间和空间限制的信息传递额交流;
Sina , QQ , 163 / 126 , Foxmail, 189, aliyun ,Outlook,Gmail
等等;发送邮件的服务器
和接收邮件的服务器
。Q:什么是电子邮箱? 答:即我们在邮件服务提供商或者说是邮件服务器上申请建立的一个账户(相当于收货地址),并且为每一个用户分配一定的空间用于保存发送的电子邮件和接收到的电子邮件;
Q:如何搭建自己的邮件服务器?需要那些技术? 答:这将是本文的核心思想,从下面的基础实例中的可以从搭建到使用。 邮件服务器需求:
什么是 A 记录?
什么是别名记录(CNAME)?
什么是 MX 记录?(重点)
Q:邮件协议的介绍:
描述:邮件协议作用是约定了邮件在网络中传输格式,便于接收发送邮件双方可以正常看到对方所发的信息(实际上是解码
)
常用的邮件协议有两种(发送和接收):
发送:
Post Office Protocol
(邮局协议)即第3个版本,它定义了邮件客户端软件与 POP3 服务器的通讯规
则。
Internet Mail Access Protocol
,它是跟POP3类似邮件访问标准协议之一。
操作都会反馈到服务器
上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动
作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱,看到的邮件以及状态都是一致的。WeiyiGeek.协议端口信息
总结:
便捷和可靠的体验
。POP3 更易丢失邮件或多次下载相同的邮件
,但 IMAP 通过邮件客户端与webmail 之间的双向同步功能很好地避免了这些问题。
WeiyiGeek.区别对应
邮箱发送流程
WeiyiGeek.发送流程
描述:说到邮件就不得不提到MIME的编码介绍(base64)及使用的意义
2.1 MIME: Multipurpose Internet Mail Extensions
描述:英国帝国大学计算机在线字典FOLDOC对MIME的解释为:多部分(multi-part)、多媒体电子邮件和WWW超文本的一种编码标准,用于传送诸如图形、声音和传真等非文本数据。MIME定义于RFC1341,用MIMENCODE的方法将二进制数据转换成为一种被称为BASE64的ASCII子集的字符的组合。
Internet上有专门讨论MIME的新闻组:comp.mail.mime
2.2 MIME编码方式简介 描述:对邮件进行编码最初的原因是因为 Internet 上的很多网关不能正确传输8bit内码的字符,比如汉字等。编码的原理就是把8bit的内容转换成7bit的形式以能正确传输,在接收方收到之后,再将其还原成8bit的内容。
在MIME协议之前,邮件的编码曾经有过UUENCODE等编码方式 ,但是由于MIME协议算法简单,并且易于扩展,现在已经成为邮件编码方式的主流,不仅是用来传输8bit的字符,也可以用来传送二进制的文件,如邮件附件中的图像、音频等信息,而且扩展了很多基于MIME 的应用。
从编码方式来说,MIME定义了两种编码方法Base64与QP(Quote-Printable)
。
“=?charset?B?xxxxxxxx?=”
表示xxxxxxxx是Base64编码,且原文的字符集是charset。在段体内则直接编码,适当时机换行,MIME建议每行最多76个字符。
Base64的算法很简单,它将字符流顺序放入一个24位的缓冲区,缺字符的地方补零。
然后将缓冲区截断成为4个部分,高位在先,每个部分6位,用64个字符重新表示。如果输入只有一个或两个字节,那么输出将用等号“=”补足。这可以隔断附加的信息造成编码的混乱。
=B3=C2=BF=A1=C7=E5=A3= AC=C4=FA=BA=C3=A3=A1
。
Quoted-printable根据输入的字符串或字节范围进行编码,若是不需编码的字符直接输出。若需要编码则先输出’=’后面跟着以2个字符表示的十六进制字节值。有的场合以“=?charset?Q?xxxxxxxx?=”
表示xxxxxxxx是Quoted-printable编码,且原文的字符集是charset。在段体内则直接编码适当时机换行,换行前额外输出一个’=’。
2.3MIME的头信息 描述:邮件头在邮件头中有很多从RFC 822沿用的域名MIME也增加了一些。
常见的标准域名和含义如下:
#域名 含义 添加者
Received 传输路径 各级邮件服务器
Return-Path 回复地址 目标邮件服务器
Delivered-To 发送地址 目标邮件服务器
Reply-To 回复地址 邮件的创建者
From 发件人地址 邮件的创建者
To 收件人地址 邮件的创建者
Cc 抄送地址 邮件的创建者
Bcc 暗送地址 邮件的创建者
Date 日期和时间 邮件的创建者
Subject 主题 邮件的创建者
Message-ID 消息ID 邮件的创建者
MIME-Version MIME版本 邮件的创建者
Content-Type 内容的类型 邮件的创建者
Content-Transfer-Encoding 内容的传输编码方式 邮件的创建者
#非标准的、自定义域名都以X-开头,例如X-Mailer, X-MSMail-Priority等,通常在接收和发送邮件的是同一程序时才能理解它们的意义。
段头
#在段头中,大致有如下一些域:
#域名 含义
Content-Type 段体的类型
Content-Transfer-Encoding 段体的传输编码方式
Content-Disposition 段体的安排方式
Content-ID 段体的ID
Content-Location 段体的位置(路径)
Content-Base 段体的基位置
有的域除了值之外,还带有参数。值与参数、参数与参数之间以“;”分隔。参数名与参数值之间以“=”分隔。
1.MIME-Version: 表示使用的MIME的版本号,一般是1.0;如:MIME-Version: 1.0
2.Content-Type: 定义了正文的类型(“主类型/子类型”的形式),我们实际上是通过这个标识来知道正文内是什么类型的文件。比如text/plain 表示的是无格式的文本正文,text/html 表示的 Html 文档,image/gif 表示的是 gif 格式的图片等等。
3.关于参数的形式,RFC里有很多补充规定,有的允许带几个参数,较为常见的有:
主类型 参数名 含义
text charset 字符集
image name 名称
application name 名称
multipart boundary 边界
4.multipart类型:邮件中常用到的复合类型,该类型表示正文是由多个部分组成的,后面的子类型说明的是这些部分之间的关系。 邮件中用到的三个类型有:
(1).multipart/alternative:表示正文由两个部分组成,可以选择其中的任意一个。主要作用是在征文同时有text格式和html格式时,可以在两个正文中选择一个来显示,支持 html 格式的邮件客户端软件一般会显示其 HTML 正文,而不支持的则会显示其Text正文;
(2).multipart/related:表示文档的多个部分是相关的,一般用来描述 Html 正文与其相关的图片。
(3).multipart/mixed:表示文档的多个部分是混合的,指正文与附件的关系。如果邮件的MIME类型是multipart/mixed,即表示邮件带有附件。
Tips:multipart类型是MIME邮件的精髓。邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。 它们之间的层次关系可归纳为下图所示:
+------------------------- multipart/mixed ----------------------------+
| |
| +----------------- multipart/related ------------------+ |
| | | |
| | +----- multipart/alternative ------+ +----------+ | +------+ |
| | | | | 内嵌资源 | | | 附件 | |
| | | +------------+ +------------+ | +----------+ | +------+ |
| | | | 纯文本正文 | | 超文本正文 | | | |
| | | +------------+ +------------+ | +----------+ | +------+ |
| | | | | 内嵌资源 | | | 附件 | |
| | +----------------------------------+ +----------+ | +------+ |
| | | |
| +------------------------------------------------------+ |
| |
+----------------------------------------------------------------------+
补充总结:从层次关系中可以看出,如果在邮件中要添加附件必须定义multipart/mixed段;如果存在内嵌资源至少要定义multipart/related段;如果纯文本与超文本共存至少要定义multipart/alternative段。
什么是“至少”?
答:如果只有纯文本与超文本正文,那么在邮件头中将类型扩大化,定义为multipart/related,甚至multipart/mixed,都是允许的。
multipart诸类型的共同特征是,在段头指定“boundary”参数字符串,段体内的每个子段以此串定界。所有的子段都以--+boundary行开始,父段则以--+boundary+--行结束
。段与段之间也以空行分隔。在邮件体是multipart类型的情况下,邮件体的开始部分(第一个“–” +boundary行之前)可以有一些附加的文本行,相当于注释,解码时应忽略。段间也可以有一些附加的文本行,不会显示出来。
些复合类型又是可以嵌套使用的,比如说一个带有附件的邮件,同时有html与text两种格式的正文,则邮件的结构是:
Content-Type: multipart/mixed
部分一:
Content Type : multipart/alternative:
Text 正文;
Html 格式的正文
部分二:
附件
邮件结束符;
由于复合类型由多个部分组成,因此需要一个分隔符来分隔这多个部分,这就是上面的邮件源文件中的boundary所描述的,对于每一个Contect type :multipart/* 的内容,都会有这么一个说明,表示多个部分之间的分隔。
含有 MIME/BASE64编码的邮件,你查看它的源码时一般都含有:“This is a multi-part message in MIME format.
”这样的句子。也可以被绝大多数的email程序进行解码,包括Netscape、MS Mail、Eudora等。这些程序可以正确识别邮件的正文,恢 MIME/BASE64 编码的部分为正确的文字或夹带的二进制文件。
#(1) 从那里发信到那里接收以及接收信息的收信人
Received: from 发信邮件服务器 (unknown [115.124.23.89])
by 收信邮件服务器 (NewMx) with SMTP id
for <收信人>; Fri, 05 Jun 2020 10:56:48 +0800
#(2) QQ相关的参数
X-QQ-FEAT: Nrj7KsauvmTPZQ**********Du8ZT3+WQp6dDEfYY=
X-QQ-MAILINFO: Nj4k/6lmmRCSyBQ**********/EB9mnO1izsI+o1HWNTKN+0+IWP
X-QQ-mid: mxsza48t时间戳-收信时间tfqsxubj9
X-QQ-ORGSender: system@notice.aliyun.com
X-QQ-XMAILINFO: NlBzqDjet/+1*********/lm+frv3kDP7DnqqWKEAAiP9c
DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed;
d=newsletter.aliyun.com; s=s1024;
t=时间戳-收信时间; h=Date:From:To:Message-ID:Subject:MIME-Version:Content-Type;
bh=wfxerPzsEEmDRDRXjMJBI13r4XrE/SOsQJOnJYilKV8=;
b=LwKBc0owsr5zgBDFwwpZl3DadzCmLooo17myWuCBjkfWRUGVPXnQ7w2idnLigyemJe0nXeZC4CVzxRUhXBbqy+8piGBYOgBTCs+TLAorsbek0DbnFmY/5psSHTzAAbXWBmKiPhklr0FYNcD7HTpXxHi6/4meSe5rNmJRGiDmPh8=
X-EnvId: 106163880073
# (3) 接收到谁的发信
Received: from mscchannel011175060107.eu13(mailfrom:system@notice.aliyun.com fp:SMTPD_----.Wrr2.i)
by smtp.aliyun-inc.com(127.0.0.1);
Fri, 05 Jun 2020 10:56:47 +0800
Date: Fri, 5 Jun 2020 10:56:47 +0800 (CST)
From: =?UTF-8?B?6Zi/6YeM5LqR?= <system@notice.aliyun.com>
To: 收信人
Message-ID: 2710120060500404702
# (4) 主题base64之UTF-8编码
Subject: =?UTF-8?B?54mp6IGU572R5bmz5Y+w5bey5pSv5oyBU0RL5Zyo57q/6KOB5Ymq?=
# (5) 前面我们所说的版MIME本
MIME-Version: 1.0
# (6) 文档类型:表示文档的多个部分是混合的,指正文与附件的关系
Content-Type: multipart/mixed;
boundary="----=_Part_2824562_163938721.时间戳-收信时间439"
# (7) 文件开始标记
------=_Part_2824562_163938721.时间戳-收信时间439
# (8) 包含文档类型
Content-Type: text/html;charset=utf-8
# (9) 文档传输编码采用QR
Content-Transfer-Encoding: quoted-printable
# (10) 文件正文 QR 以 十六进制的ASCII码表示
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.=
w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=3D"http://www.w3.org/1999/xhtml">
=09<head>
=09=09<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf=
-8" />
=09=09<title>=E9=98=BF=E9=87=8C=E4=BA=91=E5=AE=98=E7=BD=91=E7=BB=9F=E4=B8=
=80=E4=B8=9A=E5=8A=A1=E9=82=AE=E4=BB=B6=E6=A0=B7=E5=BC=8F(=E4=B8=AD=E6=96=
=87_=E4=B8=AD=E5=9B=BD=E7=AB=99)</title>
=09</head>
=09<img src=3D"http://ac.mmstat.com/aliyun.12.1?logtype=3D4&type=3Demail&ms=
gid=3D2710120060500404702&areaid=3Dcn&siteId=3Dcn"/></body>
</html>
# (11) 文档结束标准
------=_Part_2824562_163938721.时间戳-收信时间439--
环境说明:
- Windows 7
- 服务端:eyoumailserversetup.exe
- 客户端:foxMail
安装流程:
Step1.运行邮件服务器软件通常一直下一步即可安装完成,完成后打开C:\EyouMailServer\MailServer.exe
界面如下:
WeiyiGeek.步骤1
Step2.工具->系统设置->邮箱域名设置(weiyigeek.top)
WeiyiGeek.步骤2
Step3.添加新账号设置并设置密码,利用foxmail进行添加账号登陆;
WeiyiGeek.步骤3
测试搭建的邮件服务:
方式1:Telnet测试发信
# (1)连接邮件服务器smtp端口
telnet 10.20.172.110 25
#220 ESMTP 易邮邮件服务器 5.2.2004.02.18 SMTP Service Ready
# (2)helo和ehlo指令的作用是向服务器标示用户身份,返回邮件服务器身份;
ehlo weiyigeek.top
250-AUTH=LOGIN
250 AUTH LOGIN
# (3)验证用户使用auth login进行验证时用户名和密码是经过base64编码过后的字符
auth login
334 VXNlcm5hbWU6
YWRtaW4=
334 UGFzc3dvcmQ6
d2VpeWlnZWVr
235 OK # 表明验证成功
# (4)使用mail指令写一个邮件信息
mail from:<admin@weiyigeek.top>
250 OK
rcpt to:<zw@weiyigeek.top> #注意这里多个rcpt指令格式
250 OK
# (5)使用data指令开始写邮件内容
data
354 send the mail data, end with .
# (6)邮件信息头与正文
from:<admin@weiyigeek.top>
to:<zw@weiyigeek.top>
subject:Telnet send Email
Telnet smtp 25 port
# (7) 结束data指令的标志
.
250
# (8) 退出Telnet邮件服务器
quit
221 SMTP SERVICE CLOSED
WeiyiGeek.telnet
方式2:Telnet pop3 邮件查看 (常用此方法在内网中进行暴力破解)
$telnet 10.20.172.110 110
Trying 10.20.172.110...
Connected to 10.20.172.110.
Escape character is '^]'.
+OK 5.2 POP3 Service Ready
# (1) pop 用户
user zw
+OK welcome here
# (2) pop 用户密码
pass 123456
+OK
# (3) 查看邮件信息可以这里看到4封邮件349212字节
stat
+OK 4 349212
# (4) list指令列出所有的邮件
list
+OK 4 349212
1 445
2 345356
3 3116
4 295
# (5) 删除用dele+序号删除邮件(只是标记删除,退出后真的删除),
dele 1
+OK
# (6) 用rset恢复标记的邮件
rset
+Ok
# (7) retr+序号查看邮件内容。
retr 2
+OK 345356 octets
# (8) 邮件正文信息
Return-Path: <admin@weiyigeek.top>
Received: from WeiyiGeek (unknown [10.20.172.103])
by weiyigeek.top with CMailServer 5.2 SMTP; Thu, 11 Jun 2020 06:32:25 +0800
Date: Wed, 10 Jun 2020 22:33:12 +0800
From: "admin@weiyigeek.top" <admin@weiyigeek.top>
To: weiyigeek <weiyigeek@qq.com>
Cc: zw <zw@weiyigeek.top>
Subject: =?GB2312?B?suLK1Lei0MU=?=
X-Priority: 3
X-Has-Attach: no
X-Mailer: Foxmail 7.2.11.303[cn]
Mime-Version: 1.0 #信息头讲解参考上面
Message-ID: <202006102233116226900@weiyigeek.top>
Content-Type: multipart/related;
方式3.采用邮箱客户端进行登陆发信,这里不多说了(自己建的邮件服务器采用密码,如果用的是QQ采用授权码即可);
描述:老规矩我们首先需要将mail包导入到工程之中,此处采用javamail-1.4.4
版本和类型;
基础示例:
package top.weiyigeek.email;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.junit.Test;
public class emailDemo {
@Test
public void sendMail() throws AddressException, MessagingException {
//1.服务器的设置
Properties props = new Properties();
props.setProperty("mail.host", "10.20.172.110");
props.setProperty("mail.smtp.auth","true");
//2.邮箱用户账号和密码
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("admin@weiyigeek.top", "weiyigeek");
}
};
//3.建立联系返回session
Session session = Session.getDefaultInstance(props, authenticator);
//4.邮件编写与发送
//4.1 邮件编写
Message message = new MimeMessage(session);
//4.2 发件人信息
message.setFrom(new InternetAddress("admin@weiyigeek.top"));
//4.3 收件人 , to:收件人 cc:抄送 bcc:暗送(密送)。(模拟账号)
message.setRecipient(RecipientType.TO, new InternetAddress("zw@weiyigeek.top"));
//4.4 主题
message.setSubject("Java-Mail测试邮件信息....");
//4.5 内容
message.setContent("<h1 style='color:red'>测试发信信息</h1>", "text/html;charset=UTF-8");
//5.将信息进行发送:Transport
Transport.send(message);
}
}
执行结果:(内部测试)
[2020-06-11 18:30:40] SMTP 10.20.172.103 ESMTP authentication: admin@weiyigeek.top
[2020-06-11 18:30:40] SMTP 10.20.172.103 mail from admin@weiyigeek.top to zw@weiyigeek.top successfully
[2020-06-11 18:30:59] SMTP MailUndeliverable mail from admin to admin@weiyigeek.top successfully
WeiyiGeek.测试
实际案例: 利用了RedisPool+javamail实现用户发信与激活;
邮件激活发信页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Email邮箱验证测试</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function(){
$("#getCode").click(function(){
var email = $("#email").val();
console.log(email);
$.get("/Web/UserOper?method=activeEmail&email="+email,function(data,status){
console.info(data);
})
});
});
</script>
</head>
<body>
<div class="container" id="activeemail">
<h1> 邮箱激活 </h1>
<form class="form-horizontal" role="form" action="UserOper?method=vertyEmail">
<label lass="col-sm-2 control-label" for="email">邮箱地址:</label>
<div class="form-group">
<div class="col-sm-6">
<input type="text" class="form-control" id="email" value="zw@weiyigeek.top" disabled>
</div>
</div>
<label lass="col-sm-2 control-label" for="emailcode">邮箱验证码:</label>
<div class="form-group">
<div class="col-sm-4">
<input type="text" class="form-control" id="emailcode" placeholder="请输入验证码" name="emailcode">
</div>
<div class="col-sm-2">
<input type="button" class="btn btn-default" value="获取验证码" id="getCode">
</div>
</div>
<button type="submit" class="btn btn-primary">提交验证</button>
</form>
</div>
</body>
</html>
请求部分servlet方法(采用反射进行实现):
/Web/src/top/weiyigeek/baseservlet/BaseServlet.java
/***
* @author WeiyiGeek
* @desc 工具类:自建一个Servlet基础类所有继承该类的Servlet都将执行重写后的Service方法
*/
public class BaseServlet extends HttpServlet {
@SuppressWarnings("unused")
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BaseServlet - 被继承的基础Servlet中的Service方法");
//1.获取请求的操作的方法
String method = req.getParameter("method");
//2.定义转发路径
String redirection = null;
//3.获取当前的字节码对象
Class<? extends BaseServlet> clazz = this.getClass(); //此时获取的实际上是继承者的class即 UserOper.class
try {
//4.采用反射reflect形式获取到clazz的方法并且进行调用传入的指定方法
Method md = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
if (null != md) {
redirection = (String) md.invoke(this, req, resp);
}
//5.当跳转路径不为空的时候返回的指定路径
if (null != redirection){
req.getRequestDispatcher(redirection).forward(req, resp);
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
/Web/src/top/weiyigeek/baseservlet/UserOper.java
public class UserOper extends BaseServlet {
private static final long serialVersionUID = 1L;
public UserOper() {
super();
System.out.println("UserOper Servlet 构造方法!");
}
public String activeEmail(HttpServletRequest request,HttpServletResponse response) throws ServerException {
System.out.println("邮件发信");
return "/SendMail";
}
}
注册邮件发送servlet:
package top.weiyigeek.baseservlet;
import java.io.IOException;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import redis.clients.jedis.Jedis;
import top.weiyigeek.connredis.RedisDemo3;
import top.weiyigeek.email.Email;
import top.weiyigeek.utils.RedisPoolUtil;
public class SendMail extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.返回类型
response.setContentType("application/json;charset=utf-8");
//2.redis相关
Jedis jedis = RedisPoolUtil.getJedis();
//3.客户端session
HttpSession session = request.getSession();
String sessionid = session.getId();
//4.获取得到的email(生成激活码)
String email = request.getParameter("email");
String emailcode = String.format("%04d", new Random().nextInt(10000));
String context=" <h3 style='color:grade'>欢迎注册WeiyiGeek博客</h3><br><b>邮箱激活验证码:"+emailcode+"</b>";
//5.判断是否激活邮箱否则发信
if(!RedisDemo3.exits(jedis, sessionid) && !RedisDemo3.exits(jedis, email)) {
System.out.println("session:"+sessionid+" emailcode:"+emailcode);
try {
RedisDemo3.setKeyString(jedis, sessionid, emailcode, 360);
RedisDemo3.setKey(jedis, email, "false");
try {
Email.sendMail(email, "[注册码] weiyigeek Blog's", context);
response.getWriter().append("{\"status\":\"successful\",\"msg\":\"发信成功\"}");
} catch (Exception e) {
response.getWriter().append("{\"status\":\"Error\",\"msg\":\"发信失败,请重试!\"}");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
jedis.close();
}
}else if (!RedisDemo3.exits(jedis, sessionid) || !RedisDemo3.getKeyString(jedis, email).equals("true")) {
System.out.println("session:"+sessionid+"--激活码:"+emailcode);
try {
Email.sendMail(email, "[注册码] weiyigeek Blog's", context);
response.getWriter().append("{\"status\":\"successful\",\"msg\":\"再次发信成功\"}");
} catch (Exception e) {
response.getWriter().append("{\"status\":\"Error\",\"msg\":\"再次发信失败,请重试!\"}");
}
} else {
System.out.println("session:"+sessionid);
response.getWriter().append("{\"status\":\"error\",\"msg\":\"mail already active and verity!\"}");
}
//7.使用完毕后记得关闭redis连接并将其返还给资源池
jedis.close();
}
}
执行结果:
邮件发信
当前Redis连接池被使用的数量: 1
session:0327E936C1BB849C79410E5BEA3D55ED emailcode:8537
WeiyiGeek.示例