JavaWeb - 旅游网项目

1. 项目导入与启动

  可在EditConfiguration中编辑启动命令

2. 技术选型

  1. Web层

    (1)Servlet :前端控制器

    (2)html :视图

    (3)Filter : 过滤器

    (4)BeanUtils : 数据封装

    (5)Jackson : json序列化工具

  2. Service层

    (1)Javamail :java发送邮件的工具

    (2)Redis :nosql内存数据库

    (3)Jedis :java的redis客户端

  3. Dao层

    (1)Mysql :数据库

    (2)Druid :数据库连接池

    (3)JDBCTemplate :jdbc的工具

3. 创建数据库

-- 创建数据库
CREATE DATABASE travel;

-- 使用数据库
USE travel;

 

4.  用户注册功能

  注册功能分析:

 

 

 5. 邮箱激活

  为什么要进行邮件激活?

    * 为了保证用户填写的邮箱是正确的,将来可以推广一些宣传信息到用户邮箱中。

 

 6. 用户登录功能

 

7. 退出登录功能

    * 什么叫做登录了?session中有user对象

  * 实现步骤:

    1. 访问servlet,将session销毁

    2. 跳转到登录页面 

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

 

         // 销毁session
        request.getSession().invalidate();

        // 跳转页面
        response.sendRedirect(request.getContextPath()+"/login.html");    

 

8. 优化Servlet

  * 减少Servlet的数量,现在是一个功能一个Servlet,将其优化为一个模块一个Servlet

  * 相当于在数据库中一张表对应一个servlet,在Servlet中提供不同的方法,完成用户的请求

                         * 抽取BaseServlet

 

 

  service方法乱码问题: maven runner中设置:-Dfile.encoding=gb2312

package cn.itcast.travel.web.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class BaseServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("baseservlet的方法执行了");

        // 完成方法的分发
        // 1. 获取请求路径
        String uri = req.getRequestURI(); // 返回如:/travel/user/add
        System.out.println(uri);
        // 2. 获取方法名称
        String methodName = uri.substring(uri.lastIndexOf("/") + 1);
        System.out.println(methodName);
        // 3. 获取方法对象 this就是UserServlet对象 通过字节码文件 反射获取
        System.out.println(this); // this就是UserServlet对象
        try {
            // getDeclaredMethod会忽略方法访问权限修饰符 protected就能被访问
            Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            // 4. 执行方法
            // 暴力反射
            //method.setAccessible(true);
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}
BaseServlet

 

9. 分类数据展示功能  

 

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

 

package cn.itcast.travel.service.impl;

import cn.itcast.travel.dao.CategoryDao;
import cn.itcast.travel.dao.impl.CategoryDaoImpl;
import cn.itcast.travel.domain.Category;
import cn.itcast.travel.service.CategoryService;
import cn.itcast.travel.util.JedisUtil;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class CategoryServiceImpl implements CategoryService {
    private CategoryDao dao = new CategoryDaoImpl();
    @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){
            // 3. 如果为空,需要从数据库中查询,再将数据存入redis
            // 3.1 从数据库查询
            System.out.println("从数据库查询");
            cs = dao.findAll();

            // 3.2 将集合数据存储到redis中的key为category的sorted set中
            for (int i = 0; i < cs.size(); i++) {
                jedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());
            }
        }else {
            // 4. 如果不为空,将set的数据存入list中,要做到数据结构统一,因为后期要返回一个list集合
            System.out.println("从redis中查询");
            cs = new ArrayList<Category>();
            for (String name : categorys){
                Category category = new Category();
                category.setCname(name);
                cs.add(category);
            }
        }
        return cs;
    }
}
缓存优化

 

 10. 旅游线路的分页信息展示

   类别id的传递:

    * Redis中查询score(cid)

    * index页面传递cid(通过location.search获取cid)

 

     * 获取index页面传来的cid

 

 分析:

 

 11. 旅游线路名称查询

 

   在header.html中

 

   在route_list中获取参数

   修改后台代码:

Servlet中:

 

 

 

 

route_list.html中:

 

 

 

 

12. 旅游线路详情展示

 

 

13. 旅游线路收藏

  1. 当页面加载完成后,首先发送ajax请求,获取用户是否收藏的标记

  2. 根据标记,再去展示不同的按钮样式

 数据库表关系:

 

 

分析:

 

 14.  点击按钮收藏

 

posted @ 2020-11-14 13:21  五号世界  阅读(506)  评论(0编辑  收藏  举报