一个旅游网小Demo的总结

用户:

注册:

       验证码信息存放在session中。

       防止重复提交表单,详见:https://blog.csdn.net/YooFale/article/details/86576025

              具体实现:先findByUsername,再save。

激活:先findByCode,再updateStatus。(也可以在完成激活后清除code),需要涉及到MailUtil的发送邮件操作。

登录:findByUsernameAndPassword,登陆完成需要把用户信息存储到session中。

 

分类:

查询:findAll实现,

 public List findAll() {
//        从redis中查询
        Jedis jedis = JedisUtil.getJedis();
//        Set categorys = jedis.zrange("category", 0, -1);
        Set categorys = jedis.zrangeWithScores("category", 0, -1);
        List categoryList = null;
//        判断是否为空
        if (categorys == null || categorys.size() == 0) {
            //        为空第一次访问,需要从数据库查询,并存储在redis中
            categoryList = categoryDao.findAll();
            for (int i = 0; i < categoryList.size(); i++) {
                jedis.zadd("category", categoryList.get(i).getCid(), categoryList.get(i).getCname());
            }
        } else {
//        不为空,证明不是第一次,将redis中的数据存储到list中返回(set转存到list中)
            categoryList = new ArrayList();
//            for (String name:categorys){
//                Category category = new Category();
//                category.setCname(name);
//                categoryList.add(category);
//            }
            for (Tuple tuple : categorys) {
                Category category = new Category();
                category.setCname(tuple.getElement());
                category.setCid((int) tuple.getScore());
                categoryList.add(category);
            }
        }

        return categoryList;
    }

zrange用于按照权重(score)查询redis中存储的数据。zrangeWithScores查询的结果不仅是数据,还有对应的score。

redis中查不到需要dao,zadd(key,score,value)用于向redis中存储。

在redis中能查到,需要把redis中set格式的数据转存到list中,并返回前端。

 

商品列表查询(分页):

              首先确立pageBean的五大元素。前端需要提供的是currentPage,pageSize,cid(分类id)。

 int cid =0;
//        处理参数
        if(cidStr!=null && cidStr.length()>0 && !"null".equals(cidStr)){
            cid = Integer.parseInt(cidStr);
        }

        int pageSize = 0;
//        处理参数
        if(pageSizeStr!=null && pageSizeStr.length()>0){
            pageSize = Integer.parseInt(pageSizeStr);
        }else{
            pageSize=5;
        }

        int currentPage =0;
//        处理参数
        if(currentPageStr!=null && currentPageStr.length()>0){
            currentPage = Integer.parseInt(currentPageStr);
        }else{
            currentPage = 1;
        }

需要注意的是,cid可能为“null”。

 

搜索:  

header.html

    $("#search_button").click(function () {
            var rname = $("#search_input").val();
            var cid = getParameter("cid");
//            页面跳转
            location.href="http://localhost:8080/travel/route_list.html?cid="+cid+"&&rname="+rname;

        });

      点击按钮地址跳转

route_list.html

 var cid = getParameter("cid");
            var rname = getParameter("rname");

            if(rname){
                rname = window.decodeURIComponent(rname);
            }

            //当页码加载完成后,调用load方法,发送ajax请求加载数据
            load(cid,null,rname);

        页面加载完成获取地址栏的参数,调用方法(currentPage为null)加载数据。

        tomcat7无法处理乱码,需要手动转码:

     String rname = request.getParameter("rname");
        rname = new String(rname.getBytes("iso-8859-1"), "utf-8");

路线详情:

            domain中route不仅有tab_route中的属性,还有额外的关联对象 category,seller,routeImageList等

            在卖家表,路线表,路线图片表三个表完成查询后,统一写入route对象中。

 

收藏:

           需要注意的部分多为回显,在JQ中。

 

JQ:

              在JQ中,html方法相当于JS中的innerHtml。

             界面上用户名的回显利用存储在session中的用户信息来完成。

             window.scrollTo(0,0);定位到页面顶部

              prop方法:设置属性和值

            addClass方法:向元素添加一个类

            removeAttr方法:移除元素的某个方法

两大难点:

一。分页显示

function load(cid ,currentPage,rname){
          //发送ajax请求,请求route/pageQuery,传递cid
          $.get("route/pageQuery",{cid:cid,currentPage:currentPage,rname:rname},function (pb) {
              //1.分页工具条数据展示
              //1.1 展示总页码和总记录数
              $("#totalPage").html(pb.totalPage);
              $("#totalCount").html(pb.totalCount);
            
              var lis = "";

              var fristPage = '
  • 首页
  • '; //计算上一页的页码 var beforeNum = pb.currentPage - 1; if(beforeNum <= 0){ beforeNum = 1; } var beforePage = '
  • 上一页
  • '; lis += fristPage; lis += beforePage; //1.2 展示分页页码 /* 1.一共展示10个页码,能够达到前5后4的效果 2.如果前边不够5个,后边补齐10个 3.如果后边不足4个,前边补齐10个 */ // 定义开始位置begin,结束位置 end var 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; //判断当前页码是否等于i if(pb.currentPage == i){ li = '
  • '+i+'
  • '; }else{ //创建页码的li li = '
  • '+i+'
  • '; } //拼接字符串 lis += li; } /* for (var i = 1; i <= pb.totalPage ; i++) { var li; //判断当前页码是否等于i if(pb.currentPage == i){ li = '
  • '+i+'
  • '; }else{ //创建页码的li li = '
  • '+i+'
  • '; } //拼接字符串 lis += li; }*/ var lastPage = '
  • 末页
  • '; var nextPage = '
  • 下一页
  • '; 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 = '
  • \n' + '
    \n' + '
    \n' + '

    '+route.rname+'

    \n' + '
    \n' + '

    '+route.routeIntroduce+'

    \n' + '
    \n' + '
    \n' + '

    \n' + ' ¥\n' + ' '+route.price+'\n' + ' \n' + '

    \n' + '

    查看详情

    \n' + '
    \n' + '
  • '; route_lis += li; } $("#route").html(route_lis); //定位到页面顶部 window.scrollTo(0,0); }); }

    指定start,end的范围,确保页数控制在10左右。且当前页有额外的样式。

     

    二。路线详情

                图片拼接显示的一般控制在4张,所以遍历中i>4的时候,style:“display:none”;

                收藏按钮:

      var rid = getParameter("rid");
            $.get("route/isFavorite",{rid:rid},function (flag) {
                if(flag){
                    // 用户已经收藏过
                    //
                    //设置收藏按钮的样式
                    $("#favorite").addClass("already");
                    $("#favorite").attr("disabled","disabled");
    
                    //删除按钮的点击事件
                    $("#favorite").removeAttr("onclick");
                }else{
                    // 用户没有收藏
                }
            });

     

    Dao:

        public int findTotalCount(int cid,String rname) {
            String sql = "select count(*) from tab_route where 1=1 ";
            StringBuilder sb = new StringBuilder(sql);
    
            List params = new ArrayList();
    //        判断参数
            if(cid!=0){
                sb.append(" and cid = ? ");
                params.add(cid);
            }
            if(rname !=null && rname.length() >0){
                sb.append(" and rname like ?");
                params.add("%"+rname+"%");
            }
            sql = sb.toString();
    
            return jdbcTemplate.queryForObject(sql, Integer.class,params.toArray());
        }

                 需要注意分页查询的时候可能涉及到搜索和全查询,所以需要拼接sql。

                  JdbcTemplate中queryForObject查询不到内容会抛异常而不是返回null,在知道可能查询不到的情况下最好的处理方式是先声明为null,再将查询语句try/catch处理。

     

    BaseServlet:

                  在整合的时候,对一个类的操作要整合到同一个servlet中,在BaseServlet中有如下方法

     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        System.out.println("BaseServlet的service方法被执行了");
    //        完成方法的分发
    //               1.获取请求路径
            String uri = req.getRequestURI();       //  /travel/user/add
    //                2.获取方法名称
            String methodNName = uri.substring(uri.lastIndexOf('/') + 1);
    //                3.获取方法对象Method
            //System.out.println(this);      此时userServlet调用,所以this是userServlet
            try {
                //因为是protected,所以需要忽略权限,并添加暴力反射
                Method method = this.getClass().getMethod(methodNName, 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();
            }
        }

    service必定执行,获取路径最后的具体名,因为方法调用者是本身的servlet,所以通过反射可以直接调用具体的方法。

     public void writeValue(Object object,HttpServletResponse response) throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            response.setContentType("application/json;charset=utf-8");
            mapper.writeValue(response.getOutputStream(), object);
        }

    writeValue方法用于将结果写为json格式并以字节输出流的格式返回。              

    你可能感兴趣的:(一个旅游网小Demo的总结)