某马旅游网学习总结

一 项目部署的环境

Idea集成开发工具+jdk1.8+tomcat8.5.31+maven3.5.2+redis2.8.9

二 项目的架构

后台的架构是 servlet->service->dao

前台的架构是 html, js, css

前台和后台的交互使用的是 ajax 异步方式提交表单

三 数据库

主要有6张表,表关系如下图所示

四 项目的主要功能模块

1.注册

用户注册功能,需要输入用户名,密码,邮箱,姓名,手机号,性别,出生日期,验证码才可登录成功。在前台页面会使用正则表达式对输入的表单进行校验,合法之后才会提交到服务器。使用异步ajax的方式提交表单,目的是为了获取服务器响应的数据。

 提交表单的代码如下

$("#registerForm").submit(function(){
	//1.发送数据到服务器
	if(checkUsername() && checkPassword() && checkEmail() && checkName() && checkTelephone() && checkBirthday() && checkCheck()){
			//校验通过,发送ajax请求,提交表单的数据   username=zhangsan&password=123

			$.post("user/regist",$(this).serialize(),function(data){
					//处理服务器响应的数据  data  {flag:true,errorMsg:"注册失败"}

					if(data.flag){
						  //注册成功,跳转成功页面
						  location.href="register_ok.html";
					}else{
						  //注册失败,给errorMsg添加提示信息
						  $("#errorMsg").html(data.errorMsg);

					}
			});

	}
	//2.不让页面跳转
    return false;
    //如果这个方法没有返回值,或者返回为true,则表单提交,如果返回为false,则表单不提交
});

 用户成功注册后,会跳转到注册成功的界面,并提示用户进行激活,需要点击发送到填写邮箱的链接进行激活账号,只有激活的账号才可以登录。

在编写RegistUserServlet 代码时,需要注意先对验证码进行校验,如果验证码错误则在页面上弹出提示信息,不再查询数据库。需要查询数据库的user表中是否存在该用户名,如果存在则提示注册失败,否则数据库需要保存用户的信息,并注册成功。

发送邮件让用户点击激活的目的是为了保证用户写的邮箱是正确的,以后可以用于推广宣传信到用户邮箱中。需要开启授权码,设置发件人的账号和授权码。使用到的是MailUtils工具类,用sendMail方法完成邮件发送。

2.登录

用户输入账号和密码,首先判断验证码是否正确,如果正确则需要查询账号和密码和数据库中的是否一致,并且查询数据库中用户的激活状态,如果是激活状态才可以登录成功,否则则需要去激活账号。

 如果登录成功后,需要在页面上显示当前登录的用户名称,即欢迎回来,xxx。那么在servlet中需要从session中获取登录用户,并将该user写回至客户端,在写回时使用了序列化json

Object user = request.getSession().getAttribute("user");
//将user写回客户端

ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json;charset=utf-8");
mapper.writeValue(response.getOutputStream(),user);

3.退出

将session对象进行销毁,并跳转到登录页面即可。

//1.销毁session
request.getSession().invalidate();
//2.跳转页面
response.sendRedirect(request.getContextPath()+"/login.html");

4.导航条展示

展示效果如下图所示

具体的逻辑分析如下

 

展示时需要知道其cid的值,该值是根据表category查询得到的,根据cid知道当前显示的是哪一类,并进行展示,还是需要查询数据库tab_route展示数据的详细信息。前台代码如下

//查询分类数据
$.get("category/findAll",{},function (data) {

    var nav_cid = getParameter("cid");
    // alert(nav_cid);

    //[{cid:1,cname:国内游},{},{}]
    if(nav_cid == 1){
          var lis = '<li class="nav-active"><a href="index.html">首页</a></li>';
    }else{
          var lis = '<li><a href="index.html">首页</a></li>';
    }

    // var lis = '<li><a href="index.html">首页</a></li>';
    //遍历数组,拼接字符串(<li>)
    for (var i = 1; i < data.length-1; i++) {
         if(nav_cid == data[i].cid){
              var li = '<li class="nav-active"><a href="route_list.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';
         }else{
              var li = '<li><a href="route_list.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';
         }

         lis += li;

    }

    //拼接收藏排行榜的li,<li><a href="favoriterank.html">收藏排行榜</a></li>
    if(nav_cid == 10){
          lis+= '<li class="nav-active"><a href="favoriterank.html">收藏排行榜</a></li>';
    }else {
          lis+= '<li><a href="favoriterank.html">收藏排行榜</a></li>';
    }

    // lis+= '<li><a href="favoriterank.html">收藏排行榜</a></li>';
    //将lis字符串,设置到ul的html内容中
    $("#category").html(lis);

    //定位到页面的顶部
    window.scrollTo(0,0);
});

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

@Override
public List<Category> findAll() {
    //1.从redis中查询
    //1.1获取jedis客户端
    Jedis jedis = JedisUtil.getJedis();
    //1.2可使用sortedset排序查询
    Set<String> categorys = jedis.zrange("category", 0, -1);
    List<Category> cs = null;
    //2.判断查询的集合是否为空
    if (categorys == null || categorys.size() == 0) {

        System.out.println("从数据库查询....");
        //3.如果为空,需要从数据库查询,在将数据存入redis
        //3.1 从数据库查询
        cs = categoryDao.findAll();
        //3.2 将集合数据存储到redis中的 category的key
        for (int i = 0; i < cs.size(); i++) {

            jedis.zadd("category", cs.get(i).getCid(), cs.get(i).getCname());
        }
    } else {
        System.out.println("从redis中查询.....");

        //4.如果不为空,将set的数据存入list
        cs = new ArrayList<Category>();
        for (String name : categorys) {
            Category category = new Category();
            category.setCname(name);
            cs.add(category);

        }
    }


    return cs;
}

5.旅游线路的分页展示

需要在前端页面上传递cid,然后根据cid查询不同类别的旅游线路数据,并进行分页展示。

前台代码如下

$(function () {
    var search = location.search;
        // 切割字符串,拿到第二个值
    var cid = search.split("=")[1];

    //当页码加载完成后,调用load方法,发送ajax请求加载数据
    load(cid);
});

function load(cid ,currentPage){
    //发送ajax请求,请求route/pageQuery,传递cid
    $.get("route/pageQuery",{cid:cid,currentPage:currentPage},function (pb) {
        //解析pagebean数据,展示到页面上

        //1.分页工具条数据展示
        //1.1 展示总页码和总记录数
        $("#totalPage").html(pb.totalPage);
        $("#totalCount").html(pb.totalCount);

                var lis = "";

        var fristPage = '<li onclick="javascipt:load('+cid+')"><a href="javascript:void(0)">首页</a></li>';

        //计算上一页的页码
        var beforeNum =  pb.currentPage - 1;
        if(beforeNum <= 0){
            beforeNum = 1;
        }

        var beforePage = '<li  onclick="javascipt:load('+cid+','+beforeNum+')" class="threeword"><a href="javascript:void(0)">上一页</a></li>';

        lis += fristPage;
        lis += beforePage;
        //1.2 展示分页页码
        /*
            1.一共展示10个页码,能够达到前5后4的效果
            2.如果前边不够5个,后边补齐10个
            3.如果后边不足4个,前边补齐10个
        */

        // 定义开始位置begin,结束位置 end
        var begin; // 开始位置
        var end ; //  结束位置


        //1.要显示10个页码
        if(pb.totalPage < 10){
            //总页码不够10页

            begin = 1;
            end = pb.totalPage;
        }else{
            //总页码超过10页

            begin = pb.currentPage - 5 ;
            end = pb.currentPage + 4 ;

            //2.如果前边不够5个,后边补齐10个
            if(begin < 1){
                begin = 1;
                end = begin + 9;
            }

            //3.如果后边不足4个,前边补齐10个
            if(end > pb.totalPage){
                end = pb.totalPage;
                begin = end - 9 ;
            }
        }


        for (var i = begin; i <= end ; i++) {
            var li;
            //判断当前页码是否等于i
            if(pb.currentPage == i){

                li = '<li class="curPage" onclick="javascipt:load('+cid+','+i+')"><a href="javascript:void(0)">'+i+'</a></li>';

            }else{
                //创建页码的li
                li = '<li onclick="javascipt:load('+cid+','+i+')"><a href="javascript:void(0)">'+i+'</a></li>';
            }
            //拼接字符串
            lis += li;
        }





             var lastPage = '<li class="threeword"><a href="javascript:;">末页</a></li>';
        var nextPage = '<li class="threeword"><a href="javascript:;">下一页</a></li>';

        lis += nextPage;
        lis += lastPage;


        //将lis内容设置到 ul
        $("#pageNum").html(lis);



        
        //2.列表数据展示
        var route_lis = "";

        for (var i = 0; i < pb.list.length; i++) {
            //获取{rid:1,rname:"xxx"}
            var route = pb.list[i];

            var li = '<li>\n' +
                '                        <div class="img"><img src="'+route.rimage+'" style="width: 299px;"></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>&yen;</span>\n' +
                '                                <span>'+route.price+'</span>\n' +
                '                                <span>起</span>\n' +
                '                            </p>\n' +
                '                            <p><a href="route_detail.html">查看详情</a></p>\n' +
                '                        </div>\n' +
                '                    </li>';
            route_lis += li;
        }
        $("#route").html(route_lis);

        //定位到页面顶部
        window.scrollTo(0,0);
    });

}

6.旅游线路详情展示

在展示旅游线路的详情时,需要传入rid才能显示具体的线路详情。

//1.获取rid
var rid = getParameter("rid");

//2.发送请求请求 route/findOne
 $.get("route/findOne",{rid:rid},function (route) {
     //3.解析数据填充html
     $("#rname").html(route.rname);
     $("#routeIntroduce").html(route.routeIntroduce);
     $("#price").html("¥"+route.price);
     $("#sname").html(route.seller.sname);
     $("#consphone").html(route.seller.consphone);
     $("#address").html(route.seller.address);

     //图片展示

     var ddstr = '<a class="up_img up_img_disable"></a>';

     //遍历routeImgList
     for (var i = 0; i < route.routeImgList.length; i++) {
         var astr ;
         if(i >= 4){
             astr = '<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'" style="display:none;">\n' +
                 '                        <img src="'+route.routeImgList[i].smallPic+'">\n' +
                 '                    </a>';
         }else{
             astr = '<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'">\n' +
                 '                        <img src="'+route.routeImgList[i].smallPic+'">\n' +
                 '                    </a>';
         }


         ddstr += astr;
     }
     ddstr+='<a class="down_img down_img_disable" style="margin-bottom: 0;"></a>';

     $("#dd").html(ddstr);

     //图片展示和切换代码调用
     goImg();
 });

7.旅游线路收藏

首先需要先判断用户是否登录,如果未登录,需要先登录。然后查询数据库判断用户是否收藏过该线路,具体是根据rid查询tab_favorite表。如果用户已经收藏该路线,需要切换按钮的样式,将属性改为不可点击。

$(function () {
   // 发送请求,判断用户是否收藏过该线路
    var rid = getParameter("rid");
    $.get("route/isFavorite",{rid:rid},function (flag) {
        if(flag){
            // 用户已经收藏过
            //<a  class="btn already" disabled="disabled">
            //设置收藏按钮的样式
            $("#favorite").addClass("already");
            $("#favorite").prop("disabled",disabled);



        }else{
            // 用户没有收藏
        }
});

如果用户没有收藏过该线路,则可以点击按钮收藏该线路,具体分析如下图所示

$(function () {
   // 发送请求,判断用户是否收藏过该线路
    var rid = getParameter("rid");
    $.get("route/isFavorite",{rid:rid},function (flag) {
        if(flag){
            // 用户已经收藏过
            //<a  class="btn already" disabled="disabled">
            //设置收藏按钮的样式
            $("#favorite").addClass("already");
            $("#favorite").attr("disabled","disabled");

            //删除按钮的点击事件
            $("#favorite").removeAttr("onclick");
        }else{
            // 用户没有收藏
        }
    });



});

//点击收藏按钮触发的方法
function addFavorite(){
    var rid = getParameter("rid");
    //1. 判断用户是否登录
    $.get("user/findOne",{},function (user) {
       if(user){
           //用户登录了
            //添加功能
            $.get("route/addFavorite",{rid:rid},function () {

                //代码刷新页面
                location.reload();
            });

       }else{
           //用户没有登录
           alert("您尚未登录,请登录");
           location.href="http://localhost/travel/login.html";
       }
    })
}

 在做该项目时,感觉一些技术还是要运用熟练的,对于自己来说,比较生疏的是js,jquery,ajax,序列化json等。并且涉及到查询数据库的语句也要会写,以及JDBCTemplate的返回值是什么,这些都关系到代码的编写。在编写前端代码的html页面中,需要注意字符串的拼接方式,即单引号和双引号,如果写的不对,也会刷不出来效果。

另外在做项目时,学会使用debug也很重要,打断点调试错误,需要使用debug的方式启动整个项目。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值