时间:2024-05-04
卜凡港
摘要
当今社会,电子邮件的应用非常广泛,例如在某网站注册了一个账户,自动發送一封欢迎邮件,通过邮件找回密码,自动批量发送活动信息等。但这些应用不可能和我们自己平时发邮件一样,先打开浏览器,登录邮箱,创建邮件再发送。为了更好的做好用户注册的安全性,保证有效用户数,以及对产品接下来的相关信息的推广,本文将首先简单介绍一些相关的术语和协议,并通过Java代码来创建电子邮件,并连接邮件服务器发送邮件,以及邮件链接的验证,激活注册用户的相关功能,并对注册时产生的一定量高并发进行研究。该研究对项目开发者学习和实现服务器端与邮箱服务器之间通信功能有一定的参考价值。
【关键词】JavaMail 电子邮件 Web 高并发
随着互联网领域各项技术迅速地发展,电子邮箱已经成为现代人常用的一种联系工具,并且涉及的领域也越来越广泛,个人邮箱有时可以看作是一个身份认证的标识,可以用来进行身份确认,以及进行相关的联系活动。现在有很多WEB开发都需要JavaMail,例如,用户注册后,网站发送一封激活邮件进行验证;用户过生日,系统发送生日祝福邮件;将最新活动和优惠以邮件的形式告知会员等等。这些应用都需要开发人员使用编程发送邮件。本次设计就是基于JavaMail实现用户注册时,通过邮件对账户进行认证的完善登陆系统。通过邮箱激活注册账户,既保证了对相关账户的安全性,也拓展了信息推广的途径,这方式已经成为了很多IT公司用户注册必经步骤。整个设计采用B/S架构,在设计过程中,我们首先搭建并配置邮箱服务器端和邮件客户端,数据库采用MySQL,在数据库中建立相应数据表,导入相应的JavaMail的jar包,在eclipse平台上引用相应的API,并考虑到一定的高并发性,采取多线程,用JAVA语言进行开发邮箱验证功能。我们在最后的实验结果检测过程中,会检测分析到系统成功实现邮件发送、接收,以及点击链接后的激活功能,本次系统的设计也将对研究人员在用户安全性设计方面有一定的帮助。
1 JavaMail
JavaMail是由SUN公司发布,提供给开发者处理电子邮件相关的编程接口。JavaMail支持常用的SMTP、POP3、TMAP等邮件协议,开发人员使用JavaMail编写邮件程序时,无需考虑底层的通信细节(Socket),可以更加有效地实施邮件传输操作,同时JavaMail所提供的API也能够支持创建出各种复杂MIME格式的邮件内容。JavaMail的API结构图如图1所示。
JavaMail API提供了消息、地址和头文件等基本的邮件系统对象,即使针对不同的邮件协议,不同的厂商,都可以从JavaMail所提供的一系列接口中找到相应的实现类,从而满足开发者多方面需求。
2 邮件收发协议
协议是用来规定双方应该满足什么样的格式,回什么样格式的数据,才可以进行正常通讯的一个规定。当我们在邮箱服务器上申请空间,进行邮件的传输接收,都是默认了一种通讯协议,以便通讯的正常进行。如果让JavaMail与邮件服务器通信,就需要相应的协议支持,该部分称为服务提供者接口,也就是JavaMail自身需要的协议支持。
2.1 SMTP协议
SMTP,即简单传输协议,它是一组用于由源地址到目的地址传送邮件的规则,控制信件的中转方式,属于TCP/IP协议簇,帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP所指定的服务器,可以把E-mail在较短时间内寄到收件人的服务器上,通常把处理用户SMTP请求的邮件服务器称为SMTP服务器,SMTP服务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转电子邮件,SMTP服务器的默认端口号为25。
2.2 POP3协议
POP3,即邮局协议版本3,主要用于支持使用客户端远程管理在服务器上的邮件。如果用户想从邮箱服务器中获得或接受一封电子邮件的话,连上邮件服务器后,也需要遵循一定的通讯格式,而POP3协议就是用来定义这种通讯格式。通常把处理POP3请求的服务器称为POP3服务器,它的默认端口号为110。
3 邮件验证方案分析
移动互联网迅速发展,社交联系得越密切,社交手段越多样化,而电子邮箱也是当今社交重要方式之一,所以JavaMail在产品开发中必不可少,而了解邮箱收发过程也是很多开发人员容易忽视的一点。通过对邮件收发过程,邮件验证逻辑,以及并发量的解决方案分析可以使系统设计得更加完善。
3.1 由卜箱收发过程分析
邮箱收发过程遵循之前所讲解的邮件协议,并根据相应协议所对应的服务器进行通信,具体收发过程如图2所示。
假设现在有两个邮箱,我们想让163邮箱向126邮箱发送一封邮件,让163邮箱账户和密码通过客户端进行链接,客户端可以是网页版或者是软件版,登陆到邮箱服务器上,连接邮箱服务器中的SMTP服务器上,然后进行写邮件操作,将写好的邮件同,163邮箱的SMTP服务器连接到126邮箱的SMTP服务器上,把这封邮件发送到对方邮箱服务器的SMTP上,于是126邮箱将会把这封邮件存储到其内在的存储空间里面。收邮件过程,用户通过注册时的用户名和密码,连接到相应邮箱服务器中的POP3服务器上,找到这封邮件,并返回到客户端,用户就能看到对方发送过来的邮件,整个过程反之亦然。
3.2 验证逻辑分析
在设计过程中,在数据表中设置state字段,0为激活,1为非激活状态,当用户第一次注册后,数据表中传入相应字段,state处于非激活状态,然后发送一封激活邮件到对应的注册邮箱,用户点击邮件中的激活链接后,state由非激活状态变为激活状态。如图3所示。
邮件验证的逻辑,相对而言较为简单,在实现注册功能时,服务器产生激活码,并根据开发者的配置,给注册用户发送含有激活码链接的激活邮件,通过点击链接,改变state的取值从而实现用户激活,但如果遇上系统新开放注册,这将会产生一定量的并发量,若一定时间段内,用户一窝蜂地进行注册操作,将有可能造成SMTP服务器产生拒绝421等状态,接下来将对并发量的解决方案进行分析。
3.3 并发量分析
由于注册功能不会像电商秒杀功能一样,瞬间有上千万甚至上亿的并发量,所以考虑节约资源,且可抗住一定量的并发量,我们可将注册页面放入CDN,将发送功能采用多线程进行封装,从而达到一定量的抗并发效果。具体多线程实现逻辑如图4所示。
本次设计采用ThreadPoolExecutor线程池来实现多线程,并在线程池中设定同时运行的线程数量,线程池维护线程所允许的空闲时间的单位,以及缓冲队列,从而达到对线程池的参数的设置以及优化,在参数设置基础上,多的任务可以进行排队,从而可以实现了多线程的JavaMail并发。
4 Web邮件系统编码实现
本套系统的实现采用的是MVC框架结构,这是目前相对主流且成熟的框架,我们首先在MySQL数据库中建立数据库和相应的用户表,配置C3P0数据池链接,导入所需要的Jar包,根据MVC结构,依次从实体类,DAO层,再到业务层,最后编写注册Servlet和激活Servlet实现系统设计功能。
4.1 DAO层的实现
用户注册,首先调用数据访问层中定义的方法,通过JDBC将数据存入到数据库用户表中,state状态为。值,并随机生成一串编码,并通过程序生成含有激活码的字符串链接,然后再给用户发送一封含有该激活码链接的邮件,此时通过DAO层与数据库的交互,部分代码如下:
Connection conn=DBUtil.getConnectionn;
String sql =-insert into user(usemame,email,password,state,code)values(?,?,?,?,?)";
PreparedStatement pstmt=conn.prepareStatement(sql);
pstmt.setString(1,user.getUsemame());
pstmt.setString(2,user.getEmail());
pstmt.setString(3,user.getPasswordo);
pstmt.setlnt(4,user.getState());
pstmt.setString(5,user.getCode());
num=pstmt.executeUpdateo;
DBUtil.close(conn,pstmt,null);
DBUtil是封装好的数据库连接类,通过编写一条SQL语句,经预编译进行处理,然后一一对应进行传值,从而实现与数据库的交互。
4.2 业务层的实现
根据WC结构,我们将业务层首先规定相应方法的接口,再在业务层中定义实现类,通过继承这些接口,实现业务层中定义的相应方法。在注册功能方面,利用正则表达式验证邮箱是否符合邮箱格式,若符合生成激活码,把相应数据存入到数据库中,保存成功后通过线程方式给用户发送一封邮件,再通过调用DAO层中激活用户的方法实现激活功能,其中部分代码如下所示:
String code=CodeUtil.generateUniqueCode();
User user=new User(usemame,email,password,0,code);
UserDao userDao=newUserDaolmpl();
if(userDao.save(user)>0){
new Thread(newMailUtil(email,code)).start();
return true;
}
在抗并发上,整个事务逻辑是通过调用线程池接口,开启线程,实现用户的注册和激活功能,并在一定程度上,可以抗住一定量的用戶注册产生的并发量。
4.3 Servlet的实现
本次设计中,为了实现Web应用程序,不收到cGI程序性能的限制,我们通过采用JavaServlet来实现对数据库中的JDBCAPI进行访问,本设计涉及到的最主要的两部分Servlet是实现用户注册Servlet和激活Servlet,我们需将其首先继承 Httpservlet类,并复写doGet和doPost方法,其中部分代码如下:
String userName=request.getParameter("usemame");
String password=request.getParameter("password");
String email=request.getParameter("email");
UserService userService=newUserServiceImpl();
if(userService.doRegister(userName,password,email)){
request.setAttribute("msg","注册成功,请登录邮箱激活账号");
}else{
request.setAttribute("msg","注册失败,请检查相关信息")
}
request.getRequestDispatcher("/result.jsp").forward(request,response);
在doPost方法中接收数据,将数据进行封装,调用业务,实现业务实现类,将用户信息和激活码传递过去,根据激活码查询用户,更改用户状态,将状态0变为1,同时将激活码在相应数据设置为NULL,然后调用request的getRequestDispatcher方法进行页面跳转。
4.4 JavaMail多线程的实现
创建连接对象javax.mail.session,然后创建邮件对象javax.mail.Message,再发送一封激活邮件,某些邮箱服务器要求SMTP连接需要使用SSL安全认证,为了提高安全性,邮箱支持SSL连接,也可以自己开启,如果无法连接邮件服务器,则需仔细查看控制台打印的日志信息,如果有类似“连接失败,要求SSL安全连接”等错误,可以重新设置SMTP服务器端口,部分代码如下:
Message message=newMimeMessage(session);
message.setFrom(newIntemetAddress(from));
message.addRecipient(Message.RecipientType.TO,new IntemetAddress(email));
message.setSubject("账号激活");
String content="
这是一封激活邮件,激活请点击以下链接
";
message.setContent(content,"text/html;charset=UTF-8");
Transport.send(message);
System.out.println("邮件成功发送!");
先指定发件人电子邮箱,指定发送邮件的主机,获取系统属性,设置邮件服务器,打开认证,若是QQ邮箱,还需要通过MailSSLSocketFactory获取相关属性,当这些步骤完成后,我们将进行最后的发验证邮件操作,获取默认session对象,创建邮件对象,设置发件人,设置邮件主题,设置邮件内容,将要发送的功能封装成Runnable,最后进行发送邮件。
5 测试
本套设计系统采用的是Tomcat服务器进行运行,首先我们在注册页面中输入用户名,注册邮箱,和密码。注册完后,数据库表中会有相应的用户信息,state值为0,并我们将在注册邮箱中收到一封激活邮件,如图5所示。
当点击邮件激活码链接后,会进行页面跳转,并提示成功进行激活,然后跳转到登陆页面进行登陆操作,此时注册用户已成为有效用户,我们可以再观察数据库用户表中的相关数据,如图6所示。
从图6中我们首先可以看出注册时的数据已经成功注入到数据表中,并注意到password密码是经过MD5进行加密处理的,这样能很大程度上保证的用户的安全性,另外从后面两个字段中,并且state状态由。变1,激活码也根据之前程序设定的自动清空,该账户已经成功被激活,从而可以进行后面研发产品中任何体验操作。
6 结束语
本次验证系统设计,首先根据对SMTP和POP3邮件相关协议的了解,详细论述了邮件收发过程和注册邮件激活逻辑,并通过多线程防止高并发量造成的死锁,采用JavaMail提供的API实现邮件发送和用户的激活功能。整个系统架构采用JSP+Servlet结构,轻化了系统框架,节省了资源。在设计过程中,我们也需要注意,并不是所有的提供邮箱的网站都会对用户开通SMTP服务器,一般可以使用的SMTP服务器都需要身份验证的,且无法进行匿名发邮件。从测试结果来说,我们可以成功实现注册时产生激活码的链接,对用户发送含激活链接的邮件,用戶点击邮件中链接后,也成功实现激活用户的操作。但本次设计中,仍存在一定的缺陷,无法承担企业级的并发量,整体功能并不完善,当用程序对一个邮箱发送大量邮件,也可能会被某些邮箱服务器当作外界攻击。整体来讲,本次设计对JavaMail的运用和对邮件系统的设计有着一定的参考价值。
参考文献
[1]Bruce Eckel.Thinking in Java[M].Upper Saddle River,New Jersey,USA:Prentice Hall,2006.
[2](美)阿诺德,Ken Arnold等.Java程序设计语言[M].北京:人民邮电出版社,2006.
[3]姜承尧.高性能网站MySQL数据库实践.维普中文科技期刊数胡库,2013.
[4]林学良.JSP&Servlet学习笔记.北京:清华大学出版社,2012.
[5]罗军舟,黎波涛,杨明.TCP/IP协议及网络编程技术[M].北京:清华大学出版社,2004.
[6]何进,谢松巍.基于Socket的TCP/IP网络通讯模式研究[J].计算机应用研究,2001,18(08):134-135
[7]孙卫琴.Tomcat与Java Web开发技术详解[M].北京:电子工业出版社,2009.
[8]贺松平.基于MVC模式的B/S架构的研究及应用[D].武汉:华中科技大学,2006(04).
[9]赵俊峰等.Java Web应用开发案例教程:基于MVC模式的JSP+ServIet+JDBC和AJAX[M].北京:清华大学出版社,2012(01)
[10]张峋,杨三成.关键技术:JSP与JDBC应用详解[M].中国铁道出版社,2010(11).
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!