某马旅游网学习总结

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

相关文章

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

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

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

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

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Linux区分SSD和机械硬盘的方法总结

《Linux区分SSD和机械硬盘的方法总结》在Linux系统管理中,了解存储设备的类型和特性是至关重要的,不同的存储介质(如固态硬盘SSD和机械硬盘HDD)在性能、可靠性和适用场景上有着显著差异,本文... 目录一、lsblk 命令简介基本用法二、识别磁盘类型的关键参数:ROTA查询 ROTA 参数ROTA

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen