- 本文对应项目:目录:G:\idea_java_project 下的travel项目
- 本文参考资料《综合案例笔记》笔记
1、准备工作
项目导入
将资料的空travel项目导入IDEA中。(注意导入项目的方法,选择的是pom.xml文件,参考视频1-4.00)。
IDEA中导入Maven项目的方法:文章1 、文章2 、文章3 (根据具体情况具体分析,IDEA中有多种导入项目的方法)
我们在导入项目的过程中,可能出现项目目录不全的情况,这种情况参考文章:添加链接描述 。在import module的时候选择import modules from external model ,选择下面的Maven,这样才会导入正确的目录结构。
IDEA中如何打开多个项目:添加链接描述 。也可以在“File”选择Open,直接选择在新的窗口打开项目。
- 导入项目的过程中总有这样那样的错误,注意多尝试多查询!!细节要注意!
项目启动
我们已经在pom.xml中安装了tomcat插件,并指定相应的端口以及项目访问的虚拟目录。我们下面介绍的是通过Maven中的tomcat来运行项目。当然,也可以向上面的文章1、文章2一样,使用我们计算机安装的Tomcat来运行项目(具体参考上面文章)。
<configuration>
<!-- 通过maven tomcat7:run运行项目时,访问项目的端口号 -->
<port>80</port>
<!-- 项目访问路径 本例:localhost:9090, 如果配置的aa, 则访问路径为localhost:9090/aa-->
<path>/travel</path>
</configuration>
方法1
方法2:配置,如下(参考视频2)
我们启动项目的时候出现编译异常,出现在MailUtils类,这是因为MailUtils类的编码是UTF-8 BOM,我们需要在NotePad++中将其编码修改为UTF-8,并在IDEA中刷新项目,这样就不会出错。参考文章:添加链接描述
这个黑马旅游网的首页我们已经做过,现在只需要完成登录、注册、安全退出、页面展示、旅游线路收藏等功能即可!
技术选型
本项目的技术选型分为三层架构的3个部分,如下:
4.1 Web层
a) Servlet:前端控制器
b) html:视图 不用JSP原因:我们做的系统是互联网系统,项目是要给网上的用户访问的,这就要求用户的访问速度要快,而且可以做到真正的前后端的分离(JSP作为前端语言还是可以嵌入后端语言)。如果我们要做后台的管理系统,如办公自动化系统,财务系统等给内部人员使用的系统,就会使用JSP作为视图。 (在pom.xml中不需要配置jar包的坐标)
c) Filter:过滤器 (在pom.xml中不需要配置jar包的坐标)
d) BeanUtils:数据封装 简化将表单提交的数据封装为对象的流程
e) Jackson:json序列化工具 我们将页面数据通过异步(Ajax)的方式提交到服务器(比如注册功能,需要将用户填写的数据提交到服务器并接收服务器的响应消息),否则HTML中很难接收服务器返回给客户端的数据,而异步请求响应的过程中,我们一般会将服务器响应回客户端的数据序列化为JSON返回。
4.2 Service层(注意,将数据存储到Redis缓存,是在service业务逻辑层;注册后发送邮件的Javamail也在service层)
f) Javamail:java发送邮件工具
g) Redis:nosql内存数据库
h) Jedis:java的redis客户端
4.3 Dao层
i) Mysql:数据库
j) Druid:数据库连接池
k) JdbcTemplate:jdbc的工具
此时,pom.xml文件中已经将各个技术所需的jar包的坐标配置好了。(参考项目pom.xml文件)
创建数据库
资料中已经提供了travel数据库的原文件,我们在SQLyog中创建即可。
CREATE DATABASE travel; -- 创建数据库
USE travel; -- 使用数据库
-- 下面就是创建表的语句
复制提供好的sql
下面是我们首先使用到的tab_user表,结构如下:
首先是用户管理相关的功能:用户的注册、登录、以及退出功能
1、注册功能
注册功能分析(视频5)
见视频5分析
注册功能-前台-表单校验+异步提交表单数据
包括表单的校验以及校验正确后表单数据的异步提交。具体见regist.html代码解析。
1、表单校验部分;
2、数据的异步提交部分;
为什么自己定义的方法不能写在window.onload()中:添加链接描述
为什么使用异步提交表单的方法:在此使用异步提交表单是为了获取服务器响应的数据。因为我们前台使用的是html作为视图层,不能够向JSP一样直接从servlet相关的域对象获取返回提示信息的值,只能通过ajax获取响应数据JSON。
注册功能-后台-Servlet的实现+service层+dao层实现
步骤
1、首先我们设置处理整个项目Request与Response编码问题的过滤器:CharchaterFilter;
2、其次是处理注册请求的Servlet:RegistUserServlet;
3、这里需要创建一个用户表user表的实体类:User,以及用于封装后端返回前端数据对象的类:ResultInfo;
4、编写service层UserService类的方法:regist();
5、编写dao层的UserDao类的方法:findByUsername(String username)方法以及save(User user),此处使用到JDBCTemplate,需要添加JDBC工具类JDBCUtils;
编写后我们在register.html填写数据并点击注册(异步提交,因此注册页面不会提交表单跳转页面,没有任何反应),发现数据库添加一行数据。我们多次使用同一数据提交注册,IDEA控制台没有反应,且数据库的数据不会增加。
注册功能-前台返回数据的处理+后台验证码
步骤
1、后台RegistUserServlet先对验证码进行判断,正确执行下面内容,不正确返回错误信息给register.html;
2、前台处理返回数据,首先在表单前面添加一个div用于显示注册失败的提示信息,处理异步请求返回的JSON数据data;
测试:注册时没有填写验证码,验证码错误;验证码正确其他信息错误,无法提交;全部填写正确,用户名重复,提交注册,页面显示“用户名重复!!!”;将用户名修改,再次提交,跳转到注册成功页面,且数据库更新一个用户数据;(注意,每次重新提交都要刷新验证码,否则验证码会出错!)
注册功能-邮件激活分析
为什么要进行邮件激活?为了保证用户填写的邮箱是正确的。将来可以推广一些宣传信息,到用户邮箱中。
//分为2个部分
1、给用户发送邮件;这个是复杂功能,我们在Service层进行操作;
2、用户点击邮件实现激活;
注册功能-邮件激活-发送邮件
发送邮件的功能一般都是由工具类来实现,我们不需要会编写工具类,只要看得懂拿过来修改即可!我们的工具类是:MailUtils (见视频14对其分析)。
注意,邮箱在使用的时候,如果是qq邮箱,MailUtils 的成员变量PASSWORD可以直接填写自己的qq邮箱密码(我们也给qq邮箱设置客户端授权码);如果是163邮箱,PASSWORD要填写授权码;
- 授权码:登录163邮箱,设置 -> POP3/SMTP/IMAP -> 客户端授权密码 ,选择开启客户端授权码。授权码是用于登录第三方邮件客户端的专用密码,开启这个授权码,我们的MailUtils才能登录邮箱。!
测试MailUtils能否发送邮件,我们在MailUtils中创建一个测试方法,我们直接在MailUtils中点击运行这个方法,我们的邮箱就会收到一封邮件。
public static void main(String[] args) throws Exception {
// 做测试用
MailUtils.sendMail("收件人邮箱(使用自己的163邮箱)","你好,这是一封测试邮件,无需回复。","测试邮件");
System.out.println("发送成功");
}
注意,这里设置自己qq邮箱(195那个)以及163邮箱的客户端授权码,使用qq邮箱作为发送,使用163邮箱作为接收,最后163邮箱成功收到邮件。这里,MailUtils就是获取qq邮箱的授权作为发送方(需要使用qq邮箱的客户端授权码),然后将邮件发送到163邮箱(只要有邮箱即可,不需要授权码)。
我们下面在实现发送邮件给你的时候,使用自己的qq邮箱作为发送方(将qq邮箱与客户端授权码赋予MailUtils的USER与PASSWORD即可),然后获取填写的用户的邮箱,调用MailUtils的sendMail方法,将相应的数据发送到用户邮箱。
注册功能-邮件激活-点击激活用户分析
最重要的是要发送什么内容给用户才能激活,那么怎么样才算激活?我们使用User实体类中的一个成员变量status表示激活状态,Y代表激活,N代表未激活。我们注册的时候,将status设置为N,用户点击激活邮件的超链接后,将status修改为N,就代表用户激活。
另外,我们激活的时候需要区分哪一个用户的status要修改为Y。我们可以在service层查询到注册用户不存在,往数据库写数据的时候,给每一个用户生成一个随机的激活码code,携带status=N放入数据库。此时已经确认用户注册成功,我们将激活码存储到MailUtils的信息中,发送给用户邮箱,用户收到邮件后,点击携带激活码的超链接访问激活用户的Servlet,这样就可以根据激活码查询User对象,将对应User对象的Status修改为Y。(不用uid区分用户是因为uid很容易被猜到!)
需要注意,发送邮件的功能我们在service业务逻辑层处理,因为dao层只处理简单的逻辑,而web层的Servlet用来控制页面。我们在service的regist方法已经可以确定注册成功,就可以在这里发送邮件激活!
另外,我们使用UuidUtil根据类来获取随机的激活码(会用即可!)
步骤
1、在service层,发现用户名不重复,可以注册之后,我们需要设置status以及激活码code,将这两个存储到User对象。
2、在service层,可以注册并往数据库写入相应的信息后,就要发送激活邮件,激活邮件携带用户的唯一标识激活码,发送给用户;
测试:
1、将注册用户邮箱填写为自己的163邮箱,将发送邮件的官方邮箱填写为自己的qq邮箱;
2、访问:http://localhost/travel/register.html ,重新注册一个用户,邮箱填写为自己的163邮箱,点击注册,跳转到成功页面,然后我们的163邮箱收到一封邮件,数据库数据还没有更新(我们还没有修改DAO层的代码);
3、点击激活邮件的链接,路径为:http://localhost/travel/activeUserServlet?code=4ee7afd043534731a15e463c4f1bb568 。
注册功能-邮件激活-ActiveUSerServlet代码实现+service层、dao层的实现
步骤
1、编写激活的Servlet:ActiveUserServlet。调用service层的active方法激活用户;
2、编写service层的active方法,active方法调用dao层的findByCode方法,根据code查找用户,查找不到返回false,查找到返回true,并调用dao层的updateStatus修改状态码完成激活;
3、编写dao层的findByCode方法与updateStatus方法;
4、注意将前面的save方法添加status与code2个内容插入代码;
debug功能:将光标放到对象上面,可以看到对象内部变量的状态。
测试:
1、将注册用户邮箱填写为自己的163邮箱,将发送邮件的官方邮箱填写为自己的qq邮箱;
2、访问:http://localhost/travel/register.html ,重新注册一个用户,邮箱填写为自己的163邮箱,点击注册,跳转到成功页面,然后我们的163邮箱收到一封邮件,数据库数据更新,status=N;
3、点击激活邮件的链接,路径为:http://localhost/travel/activeUserServlet?code=4ee7afd043534731a15e463c4f1bb568 ,显示“激活成功,请登录”。我们点击登录,到login.html页面。与此同时,数据库对应用户的status变为Y。成功ÿ