某马旅游网学习总结

2023-10-31 12:18
文章标签 学习 总结 旅游网 某马

本文主要是介绍某马旅游网学习总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 项目部署的环境

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的keyfor (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的数据存入listcs = 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,结束位置 endvar 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;//判断当前页码是否等于iif(pb.currentPage == i){li = '<li class="curPage" onclick="javascipt:load('+cid+','+i+')"><a href="javascript:void(0)">'+i+'</a></li>';}else{//创建页码的lili = '<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>';//遍历routeImgListfor (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的方式启动整个项目。

这篇关于某马旅游网学习总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315291

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用