黑马旅游网项目总结
历时五天,我从头开始搭建整个项目,到今晚10点整个项目改完最后一个问题,这个项目算是告一段落,这个项目虽然简单,但却设计的非常巧妙,对我项目架构能力有很大的提高.学习方式:一个模块一个模块的看完视频,然后进行自己的代码构思,这其中不乏画图等方法.
一.项目准备
技术选型
Web层
a)Servlet:前端控制器
b)html:视图
c)Filter:过滤器
d)BeanUtils:数据封装
e)Jackson:json序列化工具
Service层
f)Javamail:java发送邮件工具
g)Redis:nosql内存数据库
h)Jedis:java的redis客户端
Dao层
i)Mysql:数据库
j)Druid:数据库连接池
k)JdbcTemplate:jdbc的工具
数据库(附上大概的图表)
二.项目流程
注册
注册功能前端部分主要是做数据的初步校验,校验通过后通过ajax请求发给后端,后端进行查表,来进行注册功能实现,其中为了以后这个网站如果有商用价值,还做了邮件激活功能,用户需进入邮箱激活账号才能进行登录操作.
登录
注册的业务完成之后,登录的就简单许多,主要是进行后端查表操作.
退出
退出的主要思想是在服务器的session域中删除掉用户信息.
优化Servlet
在前期的开发中大每一个功能都实现了一个servlet,显得冗长,对servlet的学习中,发现整个servlet是由service方法进行分发任务的,所以实现了一个BaseServlet的java文件,继承HttpServlet类然后实现service方法,通过反射调用来完成对应servlet调用(附代码如下)`
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//完成方法的分发
String uri = req.getRequestURI();
String methodName = uri.substring(uri.lastIndexOf("/")+1);
System.out.println(methodName);
//通过反射执行userServlet中的方法
try {
//获取方法
Method method = this.getClass().getMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
//执行方法
method.invoke(this,req,resp);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
public boolean checkCode(HttpServletRequest request){
String Rcode = request.getParameter("check");
if(Rcode == null){
return false;
}
//从session获取验证码
HttpSession session = request.getSession();
String Scode = (String) session.getAttribute("CHECKCODE_SERVER");
//为了保证验证码只能使用一次
session.removeAttribute("CHECKCODE_SERVER");
return Scode.equalsIgnoreCase(Rcode);
}
public void writeValueToOutputStream(Object obj,HttpServletResponse response) throws IOException {
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=UTF-8");
mapper.writeValue(response.getOutputStream(),obj);
}
public String writeValueToString(Object obj) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);
}
}
旅游线路分页查询
点击了不同的分类后,将来看到的旅游线路不一样的。通过分析数据库表结构,发现旅游线路表和分类表时一个多对一的关系.
页面加载完成之后向“ route/pageQuery ”发送Ajax请求,获取PageBean对象。
1、遍历PageBean对象的List集合拼接字符串。
2、遍历PageBean对象的TotalPage ,拼接字符串展示在分页栏。
3、分页栏优化
- 当页面数小于10页时,展示所有页码。
- 当页面数大于10页时,只展示8个页码。
- 当页码大于4时,页码按照前4后3的模式排列。
- 当前页码前后不足时,补齐8个页码。
旅游线路名称查询
1、提取名称关键字
header.html页面查询参数的传递
$("#search-button").click(function () {
//线路名称
var rname = $("#search_input").val();
var cid = getParameter("cid");
// 跳转路径 http://localhost/travel/route_list.html?cid=5,拼接上rname=xxx
location.href="http://localhost/travel/route_list.html?cid="+cid+"&rname="+rname;
});
route_list.html页面查询参数的传递
var cid = getParameter("cid");
//获取rname的参数值
var rname = getParameter("rname");
//判断rname如果不为null或者""
if(rname){
//url解码
rname = window.decodeURIComponent(rname);
}
2、根据条件查询数据库
Dao层查询小技巧
Sql可以先写 “select * from tab_××× where ”
Dao层Sql的编写可以用StringBuilder字符缓冲区进行Sql的拼接
Dao层代码如下
//查询满足条件的数据条数
@Override
public int findTotalCount(int cid,String rname) {
String sql = "select count(*) from tab_route where 1=1 ";
List params = new ArrayList<>();
StringBuilder sb = new StringBuilder(sql);
if(cid != 0){
sb.append(" and cid=?");
params.add(cid);
}
if(rname != null && rname.length()>0){
sb.append(" and rname like ?");
params.add("%"+rname+"%");
}
sql = sb.toString();
return template.queryForObject(sql, Integer.class,params.toArray());
}
//查询满足条件的Route对象并封装为List集合
@Override
public List<Route> findByPage(int cid, int start, int pageSize,String rname) {
String sql = null;
List<Route> list = null;
boolean idEmpty = cid==0;
boolean nameEmpty = rname.equals(" ");
if(!idEmpty && nameEmpty){
sql = "select * from tab_route where cid=? limit ? , ? ";
list = template.query(sql,new BeanPropertyRowMapper<>(Route.class),cid,start,pageSize);
return list;
}
if(idEmpty && !nameEmpty){
sql = "select * from tab_route where rname like ? limit ? , ? ";
rname = "%"+rname+"%";
list = template.query(sql,new BeanPropertyRowMapper<>(Route.class),rname,start,pageSize);
return list;
}
if(idEmpty && nameEmpty){
sql = "select * from tab_route limit ?,?";
list = template.query(sql,new BeanPropertyRowMapper<>(Route.class),start,pageSize);
return list;
}
else{
sql = "SELECT * FROM tab_route WHERE cid=? AND rname LIKE ? LIMIT ?,?";
rname = "%"+rname+"%";
list = template.query(sql,new BeanPropertyRowMapper<>(Route.class),cid,rname,start,pageSize);
return list;
}
}
3、将数据库查询的数据展示在页面上
旅游线路的详情展示
1、点击查看详情按钮时传递当前路线的id
2、根据id查询数据库并封装为Route对象返回
3、根据Route对象的内容填充页面数据
旅游线路的收藏功能
根据 Uid和Rid查询 tab_favorite 表
-如果有数据,那么表示该线路已被该用户收藏
将收藏按钮置灰,移除Onclick()事件,并将按钮变成不可点击状态。
-如果没有数据,表示该线路没有被该用户收藏
将收藏按钮变成红色,并且加上Onclick()事件。点击按钮时发送异步请求更新数据库。
weixin_48391387: 您好 我想问一下,我运行后浏览器报404错误找不到localhost页面,怎么处理?还有验证码图片出不来
qq_42681454: 上次我这个问题你问了,不过帖子删了,把tomcat换成7.0的版本,然后多在页面等一下就行,我换了tomcat就可以了,有时候不行多等几秒也出现了
把手背后接受批评: 不知道你实际遇到的什么情况,如果你现在还没有解决的话你私聊一下我,我帮你看看。
塔米。: 请问,这个代码中验证码显示不出来,是什么原因呢?哪里需要修改一下?
把手背后接受批评: 我怀疑你这评论是用脚本刷的