本项目基于JSP+Servlet+Redis实现的旅游网系统
本项目基于用户登录,注册,退出,旅游线路查询,旅游线路展示,展示我的收藏来,展开项目总体分为Dao层,Service层,Servlet层,util层,domain层和前端页面,项目采用前后端分离技术,利用Ajax进行前后端数据交互
1 技术选型
1.1 Web层
a) Servlet:前端控制器
b) html:视图
c) Filter:过滤器
d) BeanUtils:数据封装
e) Jackson:json序列化工具
1.2 Service层
f) Javamail:java发送邮件工具
g) Redis:nosql内存数据库
h) Jedis:java的redis客户端
1.3 Dao层
i) Mysql:数据库
j) Druid:数据库连接池
k) JdbcTemplate:jdbc的工具
下面分别介绍各个阶段的实现
2.用户注册
2.1用户注册涉及账号激活,激活用邮箱激活
3.用户登录
4.用户退出
什么叫做登录了?session中有user对象。
那么退出就是将session中的user对象删除掉
实现步骤:
1.访问servlet,将session销毁
2.跳转到登录页面
代码实现:
Header.html
Servlet:
//1.销毁session
request.getSession().invalidate();
//2.跳转登录页面
response.sendRedirect(request.getContextPath()+"/login.html");
5.主页面展示用户姓名
header.html代码
$(function () {
//直接发送一个异步get提交
$.get("user/findUser",{},function (data) {
//接收服务器响应过来的User的姓名{uid:xx,username:xx,password:xx,name:'渣渣超'}
var msg = "欢迎回来,"+data.name ;
$("#span_id").html(msg) ;
}) ;
}) ;
Servlet代码
//从session中获取登录用户
Object user = request.getSession().getAttribute("user");
//将user写回客户端
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),user);
6.旅游线路分类
7.旅游线路分类展示
8.旅游线路查询
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);
}
8.2修改后台代码(修改代码用红体标注)
Servlet
public void rec(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1.从前台获取数据
String cidStr = request.getParameter("cid");
String currentPageStr = request.getParameter("currentPage");
String pageSizeStr = request.getParameter("pageSize");
String rname = request.getParameter("rname");
rname = new String(rname.getBytes("ISO-8859-1"),"utf-8");
//2.如果第一次访问,当前页码支点默认值/cid/pageSize
int cid = 0;
if(cidStr != null && cidStr.length()>0 && !"null".equals(cidStr)){
//cid存在
cid = Integer.parseInt(cidStr);
}
int currentPage = 0;
if(currentPageStr != null && currentPageStr.length()>0){
//cid存在
currentPage = Integer.parseInt(currentPageStr);
}else{
currentPage = 1;
}
int pageSize = 0;
if(pageSizeStr != null && pageSizeStr.length()>0){
pageSize = Integer.parseInt(pageSizeStr);
}else{
//默认等于5
pageSize = 5;
}
//3.从数据库中获取数据
PageBean<Route> pb = routeService.pageQuery(cid,currentPage,pageSize,rname);
//4.将pageBean对象直接返回给前台页面,发送json对象
writeValue(pb,response);
}
Service
public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize,String rname) {
PageBean<Route> pb = new PageBean<>();
//设置当前页码
pb.setCurrentPage(currentPage);
//设置总记录数(查数据库)
int totalCount = routeDao.findTotalPage(cid,rname);
System.out.println("totalCount = "+totalCount);
pb.setTotalCount(totalCount);
//设置页数
pb.setPageSize(pageSize);
//封装列表集合(查数据库)
//起始条数 = (当前页码 - 1) * 每页显示条数
int start = (currentPage - 1) * pageSize;
List<Route> list = routeDao.findByPage(cid,start,pageSize,rname);
pb.setList(list);
//计算总页数
int totalPage = totalCount%pageSize == 0 ? totalCount/pageSize:(totalCount/pageSize)+1;
pb.setTotalPage(totalPage);
return pb;
}
Dao(全部进行修改)
public int findTotalPage(int cid,String rname) {
String sql = "select count(*) from tab_route where 1 = 1";
StringBuilder sb = new StringBuilder(sql);
List list = new ArrayList();
if(cid != 0){
sb.append(" and cid = ?");
list.add(cid);
}
if(rname != null && rname.length()>0){
sb.append(" and rname like ?");
list.add("%"+rname+"%");
}
sql = sb.toString();
//查询并返回
return template.queryForObject(sql,Integer.class,list.toArray());
}
@Override
public List<Route> findByPage(int cid, int start, int pageSize,String rname) {
//sql语句
String sql = "select * from tab_route where 1 = 1 ";
StringBuilder sb = new StringBuilder(sql);
List list = new ArrayList();
if(cid != 0){
sb.append(" and cid = ?");
list.add(cid);
}
if(rname != null && rname.length()>0){
sb.append(" and rname like ?");
list.add("%"+rname+"%");
}
sb.append(" limit ?, ? ");
sql = sb.toString();
list.add(start);
list.add(pageSize);
//查询并返回
return template.query(sql,new BeanPropertyRowMapper<Route>(Route.class),list.toArray());
}
8.3修改前台代码
$(function () {
//获取cid
var cid = getParameter("cid");
//获取rname
var rname = getParameter("rname");
//如果rname不为空,
if(rname){
rname = window.decodeURIComponent(rname);
}
load(cid,null,rname);
});
function load(cid ,currentPage,rname){
//发送ajax请求,请求route/pageQuery,传递cid
$.get("route/rec",{cid:cid,currentPage:currentPage,rname:rname},function (data) {
//解析pagebean数据,展示到页面上
//获取记录数和页数
$("#totalPage").html(data.totalPage);
$("#totalCount").html(data.totalCount);
var lis = "";
if(data.currentPage != 1){
//首页
var firstPage = '<li οnclick="javascript:load('+cid+',1,\''+rname+'\')"><a href="javascript:void(0)">首页</a></li>';
//计算上一页,当前页码减一
var cur = data.currentPage>1? data.currentPage-1:1;
var beforePage = '<li class="threeword" οnclick="javascript:load('+cid+','+cur+',\''+rname+'\')"><a href="javascript:void(0)">上一页</a></li>';
lis += firstPage;
lis += beforePage;
}
/*
* 1.一共展示10个页码,能够达到前5后4
* 2.如果前面不足5个,后面补齐10个
* 3.如果后面不够4个,前面补齐10个
*/
//定义开始位置begin,结束位置end
var begin;
var end;
//1.判断总页数是否大于10,
if(data.totalPage < 10){
begin = 1;
end = data.totalPage;
}
begin = data.currentPage - 5;
end = data.currentPage + 4;
if(begin<1){
begin = 1;
end = begin + 9;
}
if(end>data.totalPage){
end = data.totalPage;
begin = end - 9>0?end-9:1;
}
for (var i = begin;i<=end;i++){
var li;
if(i == data.currentPage){
li = '<li class="curPage" οnclick="javascript:load('+cid+','+i+',\''+rname+'\')"><a href="javascript:void(0)">'+i+'</a></li>';
}else{
li = '<li οnclick="javascript:load('+cid+','+i+',\''+rname+'\')"><a href="javascript:void(0)">'+i+'</a></li>';
}
lis += li;
}
if(data.currentPage != data.totalPage){
//下一页
var next = data.currentPage == data.totalPage? data.currentPage:data.currentPage+1;
var nextPage = '<li class="threeword" οnclick="javascript:load('+cid+','+next+',\''+rname+'\')" ><a href="javascript:;">下一页</a></li>';
//末页
var lastPage = '<li class="threeword" οnclick="javascript:load('+cid+','+data.totalPage+',\''+rname+'\')"><a href="javascript:;">末页</a></li>';
lis += nextPage;
lis += lastPage;
}
$("#pageNum").html(lis);
//列表数据的显示
var list_lis = "";
//遍历后台传递过来的pageBean中的列表数据集合
for(var i = 0;i<data.list.length;i++){
var route = data.list[i];
var li = '<li>\n' +
'<div class="img"><img width="299px" src="'+route.rimage+'" alt=""></div>\n' +
' <div class="text1">\n' +
' <p>'+route.rname+'</p>\n' +
' <br/>\n' +
' <p>'+route.routeIntroduce+'</p>\n' +
' </div>\n' +
'<div class="price">\n' +
' <p class="price_num">\n' +
' <span>¥</span>\n' +
' <span>'+route.price+'</span>\n' +
' <span>起</span>\n' +
' </p>\n' +
' <p><a href="route_detail.html">查看详情</a></p>\n' +
'</div>\n' +
'</li>';
list_lis += li;
}
$("#list_page").html(list_lis);
window.scroll(0,0);
});
}
9.旅游线路详情展示
10.旅游线路收藏
11.旅游线路收藏展示