Skip to content

Abexope/ItCast-HeiMa-Travel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ItCast-HeiMa-Travel

Java Web 实践项目:黑马旅游网

项目课程链接:https://www.bilibili.com/video/BV1CE411E7h4

完整课程连接:https://www.bilibili.com/video/BV1uJ411k7wy

技术选型

经典三层架构:web层 - service层 - dao层

1. web层

  • Servlet:前端控制程序
  • HTML:前端页面(前后端分离架构,不适用JSP)
  • Filter:过滤器
  • BeanUtils:数据封装
  • Jackson:json 序列化工具,前后端数据通用传输格式

2. service层

  • JavaMail:Java 邮件工具
  • Redis:nosql 内存数据库
  • Jedis:Java 的 Jedis 客户端

3. dao层

  • mysql:关系数据库
  • druid:数据库连接池
  • Spring Jdbc Template:数据库连接工具

数据库设计

-- 船建数据库
CREATE DATABASE travel;
-- 使用数据库
USE travel;

其它建表 sql 语句详见:连接待上传GitHub后指定

数据库设计

课上功能实现

注册

注册表单如下,前台填充信息并点击注册按钮后实现账户注册。

注册功能分析

  1. 表单校验:前端接收外部输入,在浏览器端利用正则表达式实现校验并以CSS样式提示用户输入是否符合相关字段的条件。
  2. 异步(AJAX)提交表单:在此使用异步提交表单是为了获取服务器响应的数据。因为我们前台使用html作为视图层,不能够直接从servlet相关的域对象获取值,只能通过 AJAX 获取响应数据。

激活

为什么要进行邮件激活?为了保证用户填写的邮箱是正确的。将来可以推广一些宣传信息,到用户邮箱中。

邮件激活逻辑

  1. 发送邮件:在service层完成用户注册后,后端向用户提交的邮箱中发送激活邮件。
  2. 用户点击邮件激活:构造 User Bean 对象时会同时设置激活码激活状态属性,向用户发送的激活邮件中会带有激活码和激活连接。用户操作后,根据提交的激活码判断用户是否合法,合法则跳转至新的页面提示激活成功

登陆

index页面中用户名的提示

index-header

在 LoginServlet 中,在登陆成功的情况下将 loginUser 对象加入到 Session 对象中,index.html 页面会向后台会再次请求登陆用户信息,此时在 FindUserServlet 中从 Session 中获取 loginUser 对象并回写给 index.html 页面实现用户名提示。

退出

什么是退出?将用户信息从session中删除。

前端index.html中点击退出时,转向后端 exitServlet,在 exitServlet 中销毁session,同时跳转至 login.html 完成退出流程。

Servlet优化

减少Servlet的数量,现在是一个功能一个Servlet,将其优化为一个模块一个Servlet,相当于在数据库中一张表对应一个Servlet,在Servlet中提供不同的方法,完成用户的请求。

Servlet功能抽取

分类数据展示

展示效果

分类数据展示效果

功能分析

分类数据展示功能分析

代码实现

后台代码

三层架构:CategoryServlet - CategoryService - CategoryDao

功能抽取:在BaseServlet中封装了序列化json的方法

前台代码

hader.html加载后,发送ajax请求,请求category/findAll

缓存优化

分析发现,分类的数据在每一次页面加载后都会重新请求数据库来加载,对数据库的压力比较大,而且分类的数据不会经常产生变化,所有可以使用redis来缓存这个数据。

分类数据展示缓存优化

优化代码实现

期望数据中存储的顺序就是将来展示的顺序,使用redis的sortedset

旅游线路分页展示

点击了不同的分类后,将来看到的旅游线路不一样的。通过分析数据库表结构,发现,旅游线路表和分类表时一个多对一的关系

旅游线路表和分类表的关系

查询不同分类的旅游线路sql:Select * from tab_route where cid = ?;

类别id的传递

Redis中查询score(cid):页面传递cid

header.html传递cid:获取cid

根据id查询不同类别的旅游线路数据

根据id查询旅游线路

旅游线路模糊查询

旅游线路查询前端

在前端搜索框中输入关键词,后端根据前端提交的数据在数据库中做模糊查询(LIKE)。在此功能中将 Category dao 中的固定sql语句改为动态sql语句,在设置基础sql语句的基础上,根据不同的查询条件拼接对应的子句。

旅游线路详情展示

  • 前台效果

旅游线路详情前台效果

  • 功能分析

旅游线路详情展示功能分析

详情展示包括旅游线路文字信息、图片信息、商家信息。结合数据库构造。先从tab_route表中查出rid对应Route Bean对象(route),再从tab_route_img表中根据rid查询RouteImg Bean对象(routeImg),最后根据route对象中的sid属性从tab_seller表中查询Seller Bean对象(seller)。

将routeImg和seller封装至route的对应属性中,进而将route对象返回至Servlet层序列化为json对象回写给客户端浏览器。

旅游线路收藏

判断线路是否被收藏

当页面加载完成后,发送ajax请求,获取用户是否收藏的标记。根据标记,展示不同的按钮样式

  • 功能分析

线路收藏-相关数据库表格关系

线路收藏-收藏状态判断

收藏次数动态提示

在加载旅游线路详情信息时同时请求收藏次数属性(route.count)。

点击收藏按钮实现收藏操作

  • 按钮状态切换

线路收藏-按钮动态切换

前端中定义根据后端的查询结果设置收藏按钮的状态。

后端中定义添加收藏方法。

前端的收藏按钮每执行一次点击事件(向后端异步提交收藏请求)后再异步提交一次收藏状态判断请求。实现不更新页面的收藏按钮状态实时更新。

额外功能实现

自动登录

服务器与浏览器之间的通信称为Session,不同浏览器与服务器之间的Session通过id加以区分 用户通过浏览器登陆后,对应的Seesion会记住这次登陆状态。 自动登陆就是服务器回传给浏览器一个Cookie对象,这个Cookie对象携带了浏览器与服务器之间的Session ID(JSESSIONID属性值) 只要Session处于存活状态(Session结束生命周期/服务器关闭或重启都会使Session销毁),那么其能够一直保存用户的登陆状态。 服务器回写Cookie时需要设置Cookie的持久化时间(max age),用户再次经该浏览器访问服务器时会上传Cookie 服务器发现浏览器上传的Cookie中保存的JSESSIONID属性值与当前服务器中保存的Session的JSESSIONID相同,说明这是同一用户重复登陆,从而在Session中提取用户的登录信息回写给浏览器,最后再浏览器中渲染目标用户信息

查询用户收藏并展示

查询用户收藏并展示

取消收藏并更新页面展示

取消收藏功能分析

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published