殷-黑马旅游第2天V3


typora-copy-images-to: img

day02-黑马旅游

学习目标

  • 能够完成用户登录案例
  • 能够完成首页显示登录用户信息案例
  • 能够完成用户退出案例
  • 能够完成首页类别显示案例
  • 能够完成首页旅游线路精选案例
  • 能够完成分页获取国内游导航菜单旅游线路列表显示案例
  • 能够完成头部搜索旅游线路分页展现数据案例

第一章 案例–用户登录

1.1 用户登录跳转首页

1.1.1 需求分析

​ 用户到达登录页面,输入未激活的用户名与密码进行登录提示账号未激活(注意登录请求是ajax异步登录请求),用户输入已激活正确的用户名与密码进入网站首页。如果用户名与密码是错误的要有提示信息。

1.1.2 实现效果
【1】账号没激活

在这里插入图片描述

【2】账号或密码错误

在这里插入图片描述

【3】登录成功–跳转到首页

在这里插入图片描述

1.1.3 实现分析
1.1.4 实现步骤
【1】异步校验账号(email)是否已激活

​ 对email输入框绑定离焦事件。

【前端】login.html

<script>
    //校验账号是否激活
    var emailCheckFlag = false;
    $("input[name='email']").blur(function () {
        var email = this.value;
		//发请求校验账号是否已经激活
        $.get("/userServlet?methodName=isEmailActive",{email:email},function (result) {
	//没有激活
            if(!result.checkFlag) {
                $("#errorMsg").html(result.resultInfo);
                emailCheckFlag = false;
            }else {
                $("#errorMsg").html("");
                emailCheckFlag = true;
            }
        },"json");
    });
</script>

【web层】UserServlet.java

  /**
     * 校验账号是否激活
     * @param request
     * @param response
     * @throws Exception
     */
    public void isEmailActive(HttpServletRequest request,HttpServletResponse response) throws Exception {
        //1.获取请求数据
        String email = request.getParameter("email");

        //2.处理数据
        boolean checkFlag = userService.isEmailActive(email);

        //3.响应数据
        Map<String, Object> result = new HashMap<>();
        if (checkFlag) {
            //已经激活
            result.put("checkFlag", true);
        }else{
            //未激活
            result.put("checkFlag", false);
            result.put("resultInfo", "账号未激活,请先激活");
        }
        String jsonRes = JSON.toJSONString(result);
        response.getWriter().println(jsonRes);
    }

【service层】UserService.java

 boolean isEmailActive(String email);

【service层】UserServiceImpl.jva

  @Override
    public boolean isEmailActive(String email) {
        User user = userDao.queryUserByEmail(email);
        return null != user;
    }

【dao层】UserDao.java

User queryUserByEmail(String email);

【dao层】UserDaoImpl.java

    @Override
    public User queryUserByEmail(String email) {
        String sql = "SELECT * FROM tab_user WHERE email=? AND status = 1";
        try {
           return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(User.class),email);
        } catch (DataAccessException e) {
            return null;
        }
    }
【2】处理登录业务

【前端】login.html

<script>
    //异步提交登录页面表单---事件驱动
    $("#loginForm").submit(function () {

        //异步提交表单:ajax
        //提交表单数据:==》表单序列化==》 name=value&name=value
        var formData = $("#loginForm").serialize();
        $.post("/userServlet?methodName=login",formData,function(result){
            //处理响应数据
            console.log(result);
            if(result.loginFlag) {
                //登录成功: 跳转到首页
                location.href = "/index.html";
            }else{
                //登录失败:给出错误提示信息
                $("#errorMsg").html(result.errorMsg);
            }

        },"json");

        //阻止同步提交
        return false;
    });
</script>

【web层】UserServlet.java

 /**
     * 处理用户登录业务
     * @param request
     * @param response
     * @throws IOException
     */
    private void login(HttpServletRequest request,HttpServletResponse response)throws IOException {

        //1、接收请求数据:整个表单
        Map<String, String[]> map = request.getParameterMap();

        //创建一个封装结果的map
        Map<String, Object> result = new HashMap<>();
        //把map中的数据封装到user中
        User user = new User();
        try {
            BeanUtils.populate(user,map);
            //2、处理数据:
            //2.1 验证码校验:
            //用户输入的验证码
            String userCode = request.getParameter("checkCode");
            //获取服务器端生成的验证码
            String serverCode  = (String) request.getSession().getAttribute("code");
            if (!serverCode.equalsIgnoreCase(userCode)) {
                //验证码校验不通过:1、给用户提示信息;2、登录失败;
                result.put("loginFlag",false);
                result.put("errorMsg", "验证码错误!");
                //响应数据
                response.getWriter().println(JSON.toJSONString(result));
                //终止程序
                return;
            }

            //2.2 用户登录:校验过程 email,password == 数据库
            User loginUser = userService.login(user);
            if (null == loginUser) {
                //登录失败:
                result.put("loginFlag",false);
                result.put("errorMsg", "用户名或密码错误!");
            }else{
                //登录成功:把登录用户的数据保存在session中
                request.getSession().setAttribute("loginUser",loginUser);
                result.put("loginFlag",true);
            }
        } catch (Exception e) {
            e.printStackTrace();
            //登录失败:
            result.put("loginFlag",false);
            result.put("errorMsg", "服务器发生异常,请联系管理员!");
        }
        //3、响应数据
        response.getWriter().println(JSON.toJSONString(result));
    }

【service层】UserService.java

 User login(User user) throws Exception;
 /**
     * 处理登录业务
     * @param user
     * @return
     */
    @Override
    public User login(User user) throws Exception {
        //email  password:123456
        //把密码转换成密文
        String password = user.getPassword();
        String md5Pwd = Md5Util.encodeByMd5(password);
        user.setPassword(md5Pwd);


        //查询数据:email  md5Pwd
       return  userDao.queryByEmailAndPassword(user);
    }

【dao层】UserDao.java

User queryByEmailAndPassword(User user);

【dao层】UserDaoImpl.java

   /**
     *
     * 根据email和password查询数据
     * @param user
     * @return
     */
    @Override
    public User queryByEmailAndPassword(User user) {
        String sql = "SELECT * FROM tab_user WHERE email = ? AND password = ? AND status=1";
        try {
           return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), user.getEmail(), user.getPassword());
        } catch (DataAccessException e) {
            e.printStackTrace();
            return null;
        }
    }

1.2 登录成功后显示用户数据

1.2.1 案例需求

​ 登录成功之后跳转到首页,在首页显示登录者的账号信息。

在这里插入图片描述

1.2.2 实现分析
1.2.3 实现步骤
  1. header.html页面加载完成之后,发送异步请求到UserServlet中,从session中获取用户数据;
  2. 如果能够获取数据:说明用户已登录,将session中的用户数据更新到页面上;
  3. 如果不能够获取数据:说明用户尚未登录,拼接信息提示用户登录;
1.2.4 实现代码

【前端】header.html

给显示用户信息的span添加一个id属性

在这里插入图片描述

 /*
    * 页面加载完成之后,加载用户信息
    * */

    $(function () {
        $.get("userServlet?methodName=getLoginUserData",function (result) {
            console.log(result);
            //获取到数据 --- 用户已经登录
            if(result.loginFlag) {
                //显示登录信息 -- 隐藏未登录信息
                $(".login_out").hide();
                $("#userNameSpan").html(result.loginUser.name+"&nbsp;&nbsp;欢迎回来");
                console.log(result.loginUser.name);

                //未获取到数据---用户未登录
            }else{
                $(".login").hide();
            }
        },"json");

    });

【web层】UserServlet.java

 /**
     * 获取登录用户的数据
     * @param request
     * @param response
     */
    public void getLoginUserData(HttpServletRequest request, HttpServletResponse response) throws  Exception{
        //从session中获取数据
        User loginUser = (User) request.getSession().getAttribute("loginUser");
        //封装返回数据
        Map<String, Object> result = new HashMap<>();
        if (null != loginUser) {
            //用户已登录
            result.put("loginFlag", true);
            result.put("loginUser", loginUser);
        }else{
            //用户未登录
            result.put("loginFlag", false);
        }
        //响应数据
        String loginData = JSON.toJSONString(result);
        response.getWriter().println(loginData);
    }

第二章 用户退出(注销)

​ 如果用户已经登录,可点击退出按钮进行退出登录操作。

2.1 需求分析

  1. 点击退出按钮向后台发请求进行退出操作;
  2. 退出后应该清除服务器session中的用户信息,并跳转到登录页面。

2.2 实现步骤

2.2.1 修改header.html退出链接

在这里插入图片描述

2.2.2 后台退出实现
/**
     * 退出登录操作
     * @param request
     * @param response
     * @throws Exception
     */
public void loginOut(HttpServletRequest request,HttpServletResponse response) throws  Exception {
        //销毁sesiion
        User loginUser = (User) request.getSession().getAttribute("loginUser");
        if (null != loginUser) {
            //用户已登录 --- 销毁
            request.getSession().invalidate();
        }
        //响应数据:跳转到登录页面 --  转发,重定向
        response.sendRedirect("/login.html");
}

第三章 首页类别显示

3.1 需求分析

  1. 从数据库表tab_category中查询所有的类别数据,并将其展示在网页导航位置,如下图:
  2. 要求:因为项目中所有页面均需要加载类别数据,而且类别数据不会经常发生变化,所以应将其放入 缓存,以提高查询效率减轻数据库压力。

在这里插入图片描述

3.2 实现分析

3.3 实现步骤

  1. header.html页面加载完成后,发送异步请求查询类别列表;
  2. CategoryServlet类处理请求和响应,具体业务交由CategoryService处理;
  3. CategoryService中,接收请求后:从redis中获取类别数据:
    1. 如果redis中有数据:直接将数据返回;
    2. 如果redis中没有数据:
      1. 从数据库中查询类别列表数据,并将其转化成json字符串;
      2. 将json字符串存储到redis中,然后返回给web层;
  4. header.html页面获取到类别列表后,将其展示到导航栏位置;

3.4 实现代码

3.4.1 header.html页面修改

注释原数据

在这里插入图片描述

发送异步请求加载数据

$(function () {
        //加载类别列表信息
        $.get("categoryServlet?methodName=queryAllCategory",function (result) {
            console.log(result);
            //遍历categoryList数组
            var categoryHtml = "<li class='nav‐active'><a href='index.html'>首页</a></li>";
            if(result){
              $(result).each(function (index, element) {
                categoryHtml+=' <li><a href="route_list.html">'+element.cname+'</a></li>';
              });
            }
            categoryHtml+="<li><a href='favoriterank.html'>收藏排行榜</a></li>";

            //把拼接的数据插入到ul中
            $(categoryHtml).appendTo($("#categoryList"));
        },"json");
    });
3.4.2 后台实现

【web层】CategoryServlet.java

package com.heima.travel.web;

import com.heima.travel.service.CategoryService;
import com.heima.travel.service.impl.CategoryServiceImpl;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/categoryServlet")
public class CategoryServlet extends BaseServlet {
    //创建service层对象
    CategoryService categoryService = new CategoryServiceImpl();

    /**
     * 类别列表查询
     * @param request
     * @param response
     * @throws Exception
     */
    public void queryAllCategory(HttpServletRequest request,HttpServletResponse response) throws Exception {
        //调用业务层处理数据
        String categoryList = categoryService.queryAllCategory();
        //响应数据
        response.getWriter().println(categoryList);
    }
}

【service层】CategoryService.java

package com.heima.travel.service;

public interface CategoryService {
    String queryAllCategory();
}

【service层】CategoryServiceImpl.java

package com.heima.travel.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.travel.dao.CategoryDao;
import com.heima.travel.dao.impl.CategoryDaoImpl;
import com.heima.travel.model.Category;
import com.heima.travel.service.CategoryService;
import com.heima.travel.utils.JedisUtils;
import redis.clients.jedis.Jedis;

import java.util.List;

/**
 * @author buguniao
 * @version v1.0
 * @date 2019/3/20 16:09
 * @description 处理商品类别的Service
 **/
public class CategoryServiceImpl implements CategoryService {

    private CategoryDao categoryDao = new CategoryDaoImpl();


    /**
     * 查询所有的商品类别
     * @return
     */
    @Override
    public String  queryAll() {
        //添加缓存业务
        //1、优先从缓存中查:redis
        Jedis jedis = JedisUtils.getJedis();
        String  categoryJson = jedis.get("HEIMA65_CATEGORY_LIST");
        //缓存中没有:从数据库中查
        if (categoryJson == null) {
            //调用dao层查询数据
            List<Category> categoryList = categoryDao.queryAll();
            //把数据库中的数据 存储到redis中
            categoryJson = JSON.toJSONString(categoryList);
            jedis.set("HEIMA65_CATEGORY_LIST",categoryJson);
        }
        //释放资源
        JedisUtils.close(jedis);
        return categoryJson;
    }
}

【dao层】CategoryDao.java

package com.heima.travel.dao;

import com.heima.travel.model.Category;

import java.util.List;

public interface CategoryDao {
    List<Category> queryAll();
}

【dao层】CategoryDaoImpl.java

package com.heima.travel.dao.impl;

import com.heima.travel.dao.CategoryDao;
import com.heima.travel.model.Category;
import com.heima.travel.utils.C3p0Utils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class CategoryDaoImpl implements CategoryDao {
    //创建jdbctemplate
    private JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());
    /**
     * 查询所有的类别列表
     * @return
     */
    @Override
    public List<Category> queryAll() {
        String sql = "select * from tab_category";
        return jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Category.class));
    }
}
3.4.3 效果展示

在这里插入图片描述

第四章 首页精选旅游线路查询

4.1 需求分析

在首页index.html里面黑马精选位置,点击不同的人气旅游、最新旅游和主题旅游无刷新显示对应的信息。
人气旅游:是每个旅游线路收藏数量的降序获取前4条数据进行显示;
最新旅游:是每个旅游线路上架时间的降序获取前4条数据进行显示;
主题旅游:是每个旅游线路过滤为主题旅游的获取前4条数据进行显示;

4.2 实现效果

在这里插入图片描述

4.3 实现分析

​ 浏览首页发现,目前已经实现了点击不同的选项(人气旅游、最新旅游和主题旅游)显示不同的内容,但是这里不同的内容是静态的,需要前端发起ajax异步请求后端这些数据。这里点击不同选项显示不同内容是使用了
bootstrap里面的组件完成的,观察静态选取切换数据代码发现如下:

通过观察图发现,用户点击popularity选项卡,会自动显示id为popularity里面的数据,所以只需要将数据库里面
对应的数据更新到id为popularity元素的体里面,其他选项卡实现原理一样。所以需要前端提交异步获取黑马精选
相关数据,具体操作分析如下:

4.4 实现步骤

  1. index.html页面加载完成事件提交获取黑马精选旅游线路的异步请求给RouteServlet
  2. RouteServlet处理请求,调用业务逻辑类RouteService实现获取黑马精选旅游线路业务方法
  3. RouteService业务类调用数据访问类RouteDao分别获取人气旅游线路列表、最新旅游线路列表和主题旅游线
    路列表数据,并将这些列表数据存储到Map<String,List>对象中并返回
  4. RouteDao实现获取获取人气旅游线路列表、最新旅游线路列表和主题旅游线路列表数据。
  5. RouteServlet获取到黑马精选数据后,使用ResultInfo封装数据并返回json格式数据。

4.5 实现代码

【前端】发送异步请求

index.html

<script>
    //页面加载完成之后 加载黑马精选数据--人气,最新,主题旅游
    $(function () {
        //发请求
        $.get("routeServlet?methodName=routeCareChoose",function(result){
            console.log(result);
        },"json");
    });
</script>
【web层】层接收,响应数据

RouteServlet.java

package com.heima.travel.web;

import com.heima.travel.service.RouteService;
import com.heima.travel.service.impl.RouteServiceImpl;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(urlPatterns = "/routeServlet")
public class RouteServlet extends BaseServlet {

    //创建RouteService对象处理路线业务
    RouteService routeService = new RouteServiceImpl();

    /**
     * 查询黑马精选线路
     * @param request
     * @param response
     * @throws Exception
     */
    public void routeCareChoose(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //调用业务层获取数据
        String jsonRouteData = routeService.getCareChoose();
        //响应数据
        response.getWriter().println(jsonRouteData);
    }
}
【service层】处理业务逻辑

RouteService.java

package com.heima.travel.service;

public interface RouteService {
    String getCareChoose();
}
【service层】实现类
package com.heima.travel.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.travel.dao.RouteDao;
import com.heima.travel.dao.impl.RouteDaoImpl;
import com.heima.travel.model.Route;
import com.heima.travel.service.RouteService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RouteServiceImpl implements RouteService {
    //创建routeDao
    private RouteDao routeDao = new RouteDaoImpl();

    /**
     * 查询精选路线
     * @return
     */
    public String getCareChoose() {
        

        //查询人气旅游数据
        List<Route> populateRouteList =  routeDao.queryPopulateRoute();
        //查询最新旅游
        List<Route> newestRouteList = routeDao.queryNewestRoute();
        //查询主题旅游
        List<Route> themeRouteList = routeDao.queryThemeRoute();

      	//定义一个map封装数据
        Map<String, List<Route>> result = new HashMap<>();
        result.put("populate", populateRouteList);
        result.put("newest", newestRouteList);
        result.put("theme", themeRouteList);

        //将数据转化成JSON字符串返回
        String routeJson = JSON.toJSONString(result);
        return routeJson;
    }
}
【dao层】查询数据

RouteDao.java

package com.heima.travel.dao;

import com.heima.travel.model.Route;

import java.util.List;

public interface RouteDao {
    List<Route> queryPopulateRoute();

    List<Route> queryNewestRoute();

    List<Route> queryThemeRoute();
}
【dao层】实现类
package com.heima.travel.dao.impl;

import com.heima.travel.dao.RouteDao;
import com.heima.travel.model.Route;
import com.heima.travel.utils.C3p0Utils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class RouteDaoImpl implements RouteDao {
    //创建jdbcTemplate模板
    JdbcTemplate jdbcTemplate = new JdbcTemplate(C3p0Utils.getDataSource());

    /**
     * 获取人气旅游列表4条数据,人气旅游就是收藏数量降序前4条数据
     * @return List<Route>
     */
    @Override
    public List<Route> queryPopulateRoute() {
        //sql语句  rflag='1'(未删除)筛选上架旅游线路,人气按照收藏数量降序
        String sql="SELECT * FROM tab_route WHERE rflag='1' ORDER BY COUNT DESC LIMIT 0,4";
        return  jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Route.class));
    }

    /**
     * 获取最新旅游列表4条数据,根据上架时间降序获取前4条数据
     * @return List<Route>
     */
    @Override
    public List<Route> queryNewestRoute() {
        //sql语句 rflag-未删除   rdate--上架时间
        String sql = "SELECT * FROM tab_route WHERE rflag='1' ORDER BY rdate DESC LIMIT 0,4";
        return jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Route.class));
    }

    /**
     * 获取主题旅游列表4条数据
     * @return List<Route>
     */
    @Override
    public List<Route> queryThemeRoute() {
        //sql语句,isThemeTour='1'为主题旅游线路
        String sql="SELECT * FROM tab_route WHERE rflag='1' AND isThemeTour='1' ORDER BY rdate DESC LIMIT 0,4";
        return jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Route.class));
    }
}
【前端】拼接数据

index.html

第一步:删除页面上的死数据

在这里插入图片描述

第二步:动态拼接查询到的数据

<script>
    //页面加载完成之后 加载黑马精选数据--人气,最新,主题旅游
    $(function () {
        //发请求
        $.get("routeServlet?methodName=routeCareChoose",function(result){
            console.log(result);
            //前端解析数据
            var populateList = result.populate;
            var newestList = result.newest;
            var themeList = result.theme;


            //人气旅游
            var populateHtml = "";
            $(populateList).each(function (index, route) {
                populateHtml+='<div class="col-md-3">\n' +
                    '                                <a href="javascript:;">\n' +
                    '                                    <img src='+route.rimage+' alt="">\n' +
                    '                                    <div class="has_border">\n' +
                    '                                        <h3>'+route.rname+'</h3>\n' +
                    '                                        <div class="price">网付价<em>¥</em><strong>'+route.price+'</strong><em>起</em></div>\n' +
                    '                                    </div>\n' +
                    '                                </a>\n' +
                    '                            </div>'
            });
            $("#populateHtmlList").html(populateHtml);

            //TODO  -- 作业


        },"json");
    });

</script>

第五章 今日作业

  • 完成用户登录业务
  • 完成首先显示登录用户信息
  • 完成用户退出功能
  • 完成首页类别显示和缓存添加功能
  • 完成首页黑马精选旅游线路查询功能
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值