黑马旅游网站全记录

一、 项目导入

  1. 点击侧边的maven(如果没有可以在view–>tool window 中找到),点击加号,选择文件中的pom.xml文档即可导入
    在这里插入图片描述

  2. 首先预览一下静态页面
    在这里插入图片描述
    启动方式1:
    在这里插入图片描述
    在这里插入图片描述
    启动方式2:添加启动方式,点击绿色三角形启动
    在这里插入图片描述
    在这里插入图片描述

二、技术选型

  1. web:
    servlet:前端控制器
    HTML:数据展示
    filter:过滤器
    BeanUtils:数据封装
    Jackson:json序列化工具

  2. service:
    Javaemail:Java发送文件
    redis:nosql内存数据
    jedis:Java的redis的客户端

  3. Dao
    Mysql:数据库
    Druid:数据库连接池
    jdbcTemplate:jdbc的工具类

三、创建数据库

在这里插入图片描述

四、实现登录、注册、退出

各层调用图:
在这里插入图片描述

注册:在html利用js完成表单校验,使用ajax完成表单提交
注册成功,跳转成功页面
注册失败,跳转失败页面

servlet:RegisterServlet
(0.设置编码已经利用统一过滤器完成)
1.获取数据
2.封装User对象
3.调用service完成注册
4.根据service返回,提示信息:
将提示信息信息转为json
设置相应头:contentType

service:
registerUser(User user)
调用dao根据用户名查询用户
存在,返回false
不存在,调用dao保存用户信息

Dao:
1.根据用户名查询用户信息 findByUsername(string username);
2.保存用户信息 save(User user)

异步Ajax提交表单:
$(this).serialize()将表单中的数据提交成 username=xxx&&password=123 的格式
使用异步提交是为了获取服务器响应的数据,前台使用html作为视图层,不能直接从servlet相关的域对象获取值,只能通过Ajax获取

**

在编写的时候,写错了一个愚蠢的问题,导致无法访问主页,就是注释名称写错了,webServlet写成了webFilter导致无法访问网页404

**

login.jsp

简单的jquery登录验证

<script type="text/javascript">//检查用户名格式function checkUsername() {var username = $("#username").val();var reg_username = /^[A-Za-z_0-9]{4,20}$/;var flag = reg_username.test(username);if(flag){$("#username").css("border","");}else{alert("用户名格式错误");$("#username").css("border","1px solid red");//$("#addusername").html("用户名格式错误"); //要记得添加一个新的html格式}return flag;}//检查密码格式function checkPassword(){var password = $("#password").val();var reg_password = /^[A-Za-z_0-9]{4,20}$/;var flag = reg_password.test(password);if(flag){$("#password").css("border","");}else{alert("密码格式错误");$("password").css("border","1px solid red");//$("#addusername").html("用户名格式错误"); //要记得添加一个新的html格式}return flag;}//提交时检查是否正确$(function () {$("#form").submit(function () {if(checkPassword()&&checkUsername()){return true;}return false;})//失去焦点时,判断格式$("#username").blur(checkUsername);$("#password").blur(checkPassword);})</script>

在body中添加form表单将值传入Servlet

<form id="form" name="form" action="indexServlet"><div>用户名:<input type="text" id="username" name="username" placeholder="请输入用户名"></div><div>密码:<input type="text" id="password" name="password" placeholder="请输入密码"></div><div><input type="submit" id="login" name="login" value="登录"></div></form>

可以用${error}来接收后台传递的错误信息

<!--得到从后台得到的错误信息-->
<div>${error}</div>

LoginServlet

//设置编码
req.setCharacterEncoding("utf-8");
//获取用户输入的数据
String username = req.getParameter("username");
String password = req.getParameter("password");//判断用户名和密码是否正确
if(username.equalsIgnoreCase("zhangsan")&&password.equalsIgnoreCase("123456")){//用户名和密码正确,跳转至主页面req.getRequestDispatcher("/home.jsp");
}else{//用户名和密码错误,存储错误信息req.setAttribute("error","用户名或密码错误");//携带错误信息,转发到登录页面req.getRequestDispatcher("/index.jsp").forward(req,resp);}

五、注册页面的邮件激活

原因:为了保证用户填写的邮箱是正确的。可以推送广告
发送邮件:利用emailutil工具类编写
激活邮件:
激活对于数据库来说,就是将status 状态改为激活态
邮件激活分析:
在这里插入图片描述
不要再return下写代码,Java报unreachable statement错误
详细看连接:https://blog.csdn.net/qq_33915826/article/details/79246482

六、登录

在这里插入图片描述
登录之后,动态展示个人用户名称

header.html

<script>$(function () {$.get("findUserServlet",{},function (data) {//{uid:1,name:"yangcichen"}var msg = "欢迎回来,"+data.name;$("#span_username").html(msg);})})
</script>

异步交互
当页面整个访问完成之后,用ajax访问服务器查询出信息

在这里插入图片描述

七、退出

首先,应该思考一下,什么时候称作登录成功?
登录成功,就是session中有user
那么退出功能实现:
header.html

<a href="javascript:location='exitServlet';">退出</a>

1.访问servlet,将session销毁

req.getSession().invalidate();

2.跳转到登录界面跳转页面,采用重定向(路径写法为虚拟目录)

resp.sendRedirect(req.getContextPath()+"/login.html");

八、优化Servlet——BaseServlet

优化方式:减少servlet的数量,将其优化为一个模块一个Servlet

写一个模块servlet 让各个功能的servlet继承
模块servlet继承HTTPServlet

“this”–谁调用我,我代表谁

报错说明没有匹配的方法:
在这里插入图片描述
原因:方法的声明为protected,访问的时候没有权限
解决方法:

①在访问的时候忽略访问权限修饰符,此方法会忽略所有的方法

//忽略访问权限修饰符
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//执行方法
//暴力反射
method.setAccessible(true);
method.invoke(this,req,resp);

②直接将方法权限修饰符改为public,这有利于其他的私有方法被保护

又犯了一个低级错误——findOne名称写错,导致浏览器找不到

九、旅游数据的显示

分类数据展示:
原来是假数据,后期通过从后台动态生成

<div class="navitem"><ul class="nav"><li class="nav-active"><a href="index.html">首页</a></li><li><a href="route_list.html">门票</a></li><li><a href="route_list.html">酒店</a></li><li><a href="route_list.html">香港车票</a></li><li><a href="route_list.html">出境游</a></li><li><a href="route_list.html">国内游</a></li><li><a href="route_list.html">港澳游</a></li><li><a href="route_list.html">抱团定制</a></li><li><a href="route_list.html">全球自由行</a></li><li><a href="favoriterank.html">收藏排行榜</a></li></ul></div>

数据库中信息:
在这里插入图片描述
进行代码优化:页面分类数据在每一次页面加载后都会重新要求数据库来加载,对数据库的压力比较大,而且分类的数据不会经常产生变化,所以可以用redis来缓存这个数据。
在这里插入图片描述
期望数据库中存储的顺序,就是展示的数据

十、旅游线路分页展示

点击了不同的分类后,看到的旅游路线不一致。
分类和旅游线路是一对多
在这里插入图片描述
如何携带cid:

	//后台serviceSet<Tuple> categorys = jedis.zrangeWithScores("category", 0, -1);//2.判断查询的集合是否为空List<Category> cs=null;//2.1为空,第一次访问if(categorys==null||categorys.size()==0){//从数据库查询cs = categoryDao.findAll();//将集合存储到redis中的category的keyfor (int i = 0; i < cs.size(); i++) {//存储zaddjedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());}}else{//2.2不为空,将set数据存入list//前端需要List,但是此方法中返回set,进行格式转换cs=new ArrayList<Category>();for (Tuple tuple:categorys) {Category category = new Category();category.setCname(tuple.getElement());category.setCid((int)tuple.getScore());cs.add(category);}}

前端:

for(var i=0;i<data.length;i++){var li = '<li><a href="favoriterank.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';lis += li;
}

如何取cid:

<script>$(function () {var search = location.search;//alert(search);//切割获取到的字符串[?cid=5] 拿到5var cid = search.split("=")[1];})
</script>

根据cid获取不同的旅游线路数据:
在这里插入图片描述

十一、旅游线路名称查询

1.查询参数的传递
通过从route_list?cid=5 传递 route_list?cid=5&rname=xxx
传递xxx
首先获取到用户输入的rname

/*header.html*/
$("#search-button").click(function () {//后台根据这个名称进行模糊匹配var rname = $("#search_input").val();//alert(rname);var cid = getParameter("cid");//alert(cid);//跳转路径http://localhost/travel/route_list.html?cid=5//再拼接上rname=xxxlocation.href="http://localhost/travel/route_list.html?cid="+cid+"&rname="+rname;
})
/*route_list.html*/
//getParameter()方法为自己封装的字符切割函数
//获取cid
var cid = getParameter("cid");
//获取rname
var rname = getParameter("rname");
if(rname){//解码方法,获取到的rname为url需要解码rname=window.decodeURIComponent(rname);
}

2.修改之前的后台代码
Servlet、Service、Dao

tomcat7 从前端传值到后台乱码,解决办法:

//tomcat7,get请求出现乱码
rname = new String(rname.getBytes("iso-8859-1"),"utf-8");

在这里插入图片描述

出现了直接点击相关路线切换线路查询不到数据的问题:
在这里插入图片描述
传值load(5,2,‘null’)

解决办法链接
当rname为空时,前端传给RouteServlet的是“null”字符串,而不是null
所以在RouteDaoImpl中的判断参数是否有值的地方把rname当成“null”关键词(有值)来查询,而数据库没有关键词为“null”的旅游路线,所以返回0条记录,产生错误。
与之前判断为cid为’‘null’'时,有相似之处。

十二、查看旅游路线详情展示

在这里插入图片描述
出现图片展示有误:
在这里插入图片描述
通过前端断点调试发现标签使用了style="display:none;属性
如果删除其属性,图片可以正常显示,但是显示的数据css不正确
判断一下i 即每页的展示显示4个,超过4个进行隐藏

//遍历routeImgList
for (var i = 0; i < route.routeImgList.length; i++) {if(i>=4){var 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 {var astr='<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'" >\n' +'             <img src="'+route.routeImgList[i].smallPic+'">\n' +'             </a>'}ddstr+=astr;
}

十三、旅游路线收藏功能

页面加载完成后,发送ajax请求,查询数据库查看用户是否收藏过该线路
根据查询结果展示不同的样式
在这里插入图片描述
收藏字数的动态展示
点击收藏按钮:
在这里插入图片描述
给按钮绑定单击事件,点击了按钮调用js中的addFavorite()方法:

<a class="btn" id="favorite" onclick="addFavorite();"><i class="glyphicon glyphicon-heart-empty" ></i>点击收藏</a>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/22476.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亚丁游记(下)-云南篇

第八天&#xff1a;稻城&#xff0d;中甸 今天要离开四川去云南中甸。一大早&#xff0c;前一天联系好的司机开车过来&#xff0c;发现和我们昨天看的车不一样&#xff0c;车顶没有行李架。小小的面包车刚够坐下人&#xff0c;我们那么多的行李怎么放啊&#xff01;wolf急忙…

黑马旅游网站

第一次写CSDN所以不太会&#xff01; 我接下来会记录这一段时间&#xff0c;完成黑马旅游网站的代码&#xff01;我们使用的是maven框架&#xff0c;原因很简单&#xff0c;因为黑马提供了大部分的数据跟我们&#xff0c;里面有数据库表&#xff0c;数据库网页整体的容&#xf…

新加坡圣淘沙亲子游自助游景点购票攻略

新加坡圣淘沙岛有很多适合家庭亲子游的景点和游乐园&#xff0c;无论是想要感受肾上腺飙升的游乐设施&#xff0c;体验虚拟世界的惊险刺激&#xff0c;与众多名人约会&#xff0c;还是探索海洋世界&#xff0c;这里总有你想要的。 新加坡环球影城 新加坡环球影城分为七个主题景…

三亚旅游攻略-自由人实用指南

三亚&#xff0c;是个被大自然宠坏了的地方。大自然把最宜人的气候、最清新的空气、最和煦的阳光、最湛蓝的海水、最柔和的沙滩、最风情万种的少数民族、最美味的海鲜…都赐予了这座海南岛最南端的海滨旅游城市。 虽然三亚自古以来是贬官谪宦流放之地&#xff0c;可这段悲怆的历…

6-黑马旅游网-旅游线路详情

旅游线路详情 分析 后端 RouteServlet findOne方法 /*** 根据id查询一个旅游线路的详细信息* param request* param response* throws ServletException* throws IOException*/ public void findOne(HttpServletRequest request, HttpServletResponse response) throws Serv…

马来西亚之旅——吉隆坡、马六甲、槟城和亚庇攻略

之前就准备了在17年有个旅行计划&#xff0c;计划本来是台湾或者西藏&#xff0c;但是因为种种原因一直拖到清明节前半个月才定下来&#xff0c;看了一下机票&#xff0c;发现往返吉隆坡的机票价格很合适&#xff0c;所以才有了清明马来的行程。准备 机票 我们是从北京出发&a…

黑马旅游网编写练习(7)--某一旅游线路详情展示

黑马旅游网编写练习(7)–某一旅游线路详情展示 在分页展示的页面中&#xff0c;我们点击某一个旅游&#xff0c;想要查看详细信息&#xff0c;则点击了查看详情后&#xff0c;会跳转到该旅游路线对应的详细信息页面。接下来对该详细信息页面的查询与展示。 想要查看不同旅游线…

世界上唯一7星级酒店-阿联酋迪拜的Burj Al Arab旅店

全世界最贵的酒店&#xff0c;全世界曾经最高的酒店在迪拜。阿联酋迪拜的Burj Al-Arab酒店。 阿联酋迪拜的Burj Al-Arab酒店。 迪拜是阿拉伯联合酋长国的第二大城市。20世纪50年代&#xff0c;它还是阿拉伯湾一个朴素的海滨小镇&#xff0c;到了90年代以后&#xff0c;迪拜发生…

三亚自由行八天七晚旅行攻略

**文中报价为两人费用。**所有总支出低于1W 建议&#xff1a; 1、 住宿不要在一个地方住&#xff0c;三亚湾、亚龙湾等各住几天。 2、 带防晒霜和晒后修复霜&#xff0c;还有手机防水袋。 3、 自带泳衣&#xff0c;三亚买比较贵。 4、 直飞三亚比较好&#xff0c;海口转比较费时…

黑马旅游网-注册用户(二)

目录 一、注册用户-业务流程分析 1.页面效果 2.业务流程分析 二、注册用户-前端功能实现 修改register.html 1.校验用户名 2.校验密码 3.检验邮箱 4.使用ajax提交数据 5.完整代码参考 三、注册用户-后端功能实现 创建​​​​​​​RegisterUserServlet 创建UserServ…

黑马旅游网-旅游分类线路分页显示(七)

目录 一、先查旅游分类所有内容 二、查询分页数据 三、实现后端代码 RouteServlet RouteServiceImpl​​​​​​​ RouteService RouteDaoImpl RouteDao PageBean 四、分页与数据展示 修改route_list.html 修改header.html 五、测试 一、先查旅游分类所有内容 点…

ChatGPT最有实力的竞争对手Claude也开放API申请了

申请地址&#xff1a;https://www.anthropic.com/product 或者点击“阅读原文 ”直接申请

ChatGPT与低代码平台谁更适合快速开发

近来&#xff0c;关于生成式AI技术即将颠覆各个行业的预测在网络上随处可见。虽然生成式AI技术在自然语言处理、文本生成等领域已经取得了令人瞩目的成果&#xff0c;但是在低代码平台开发领域&#xff0c;尤其是在企业内部应用方面&#xff0c;其影响并不明显。 低代码平台作…

我曾做过陈士成,也做过孔乙己,还做过阿Q

一、 我现在是陈士成&#xff0c;陈士成现在是我。为什么这么说呢&#xff1f; 那年那天&#xff0c;天刚微微亮&#xff0c;似乎还在打着哈欠。我和父亲去得很早&#xff0c;为的就是在“小升初的考试成绩榜单”前面占一个有利的位置。我不记得当时穿的厚还是不厚&#xff0c;…

码农版孔乙己

改变自己 也许有一天你能改变这个世界&#xff0c;但是请在改变世界之前&#xff0c;先让自己存活下来&#xff0c;看到一篇文章分享一下不知道你们能从中看出什么呢 听人家背地里谈论&#xff0c;孔乙己原来也读过研&#xff0c;但终于没有实习经历&#xff0c;又没关系内推&a…

浅谈“孔乙己的长衫“是脱不下来还是难脱下?

名人说&#xff1a;往者不可谏&#xff0c;来者犹可追。——《论语微子篇》 创作者&#xff1a;Code_流苏(CSDN) ★温馨提示&#xff1a;以下仅代表个人观点&#xff0c;不代表其它任何人看法。 目录 〇、缘由一、社会对于学历和职业之间的关系认知是怎样的&#xff1f;二、学历…

Unity 蒙皮动画 SkinnedMesh 使用GPU Instance

GPU Instance合批技术是不支持 SkinnedMeshRender的&#xff0c;不过可以转换为Mesh Render以支持GPU Instance. 0x00 前言 我想很多开发游戏的小伙伴都希望自己的场景内能渲染越多物体越好&#xff0c;甚至是能同时渲染成千上万个有自己动作的游戏角色就更好了。 但不幸的是…

Unity毛发系统TressFX Exporter

Unity 数字人交流群&#xff1a;296041238 一&#xff1a;在Maya下的TressFX Exporter 插件安装步骤&#xff1a; 1. 下载Maya的TressFX Exporter插件 下载地址&#xff1a;TressFX Exporter 链接&#xff1a;https://github.com/Unity-China/cn.unity.hairfx.core/tree/m…

vscode配置go开发环境,插件超时问题解决

今天想试下golang&#xff0c;用goland太贵所以打算配置vscode来试一试&#xff0c;但是发现许多插件安装超时&#xff0c;查阅资料说是配置一下环境变量开启代理就好&#xff0c; go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.io,direct 但是尝试后发现依然没…

解决IDEA插件安装慢、超时、不成功问题

解决IDEA插件安装慢、超时、不成功问题 1.修改本地hosts文件&#xff0c;打开文件位置&#xff1a; Windows 系统 Hosts 文件路径&#xff1a;C:\Windows\System32\drivers\etc\hosts 用工具打开hosts文件 2.打开国内插件的节点IP地址 http://tool.chinaz.com/speedtest/pl…