javaee之黑马旅游网3

news2025/1/4 22:00:37

下面来说一个问题,就是对于一张表的操作,涉及到了很多的servlet页面

比如对于一个user表,里面有很多的相关的servlet页面

如果是这样一种情况,那么user表涉及到七八个页面,category表又涉及到七八个页面,那么整个项目下来servlet页面会多的不计其数。所以我们必须想个办法减少servlet的数量。

先来说一下页面实现原理

看一下servlet的实现原理

 

先来做一个都兜底的页面BaseServlet,他必须是一个Servlet,所以必须继承HttpServlet页面 

先来说一下这个页面的设计思想

再来说一下在BaseServlet页面中service方法的设计原理

 先来看兜底servlet 页面

BaseServlet

package 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;

@WebServlet("/baseServlet")
public class BaseServlet extends HttpServlet {

    //重写一下sevice方法
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取资源请求路径
        //getRequestURI
        String uri = req.getRequestURI();
        //获取路径中某个具体方法
        //针对于这个项目的uri可能会返回/travel/user/add
        //我们要的就是add这个方法名
        String methodName = uri.substring(uri.lastIndexOf('/') + 1);
        //获取方法对象的method
        //之前就说了,比如访问UserServlet,调用service方法的就是UserServlet对象
        //利用反射技术来做
        try {
            Method method = this.getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
            //暴力反射
            //method.setAccessible(true);
            //执行方法
            method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

再来看其他两个servlet页面

这里多说一点,一个servlet本质是一个Java开发的小程序,只有servlet页面的java文件才能识别,我们知道servlet里面有两个对象,一个request对象,一个response对象,这两个对象,可以接收和处理前端传过来的数据。这个对象也可以写到我们自己定义的方法里面去。

UserServlet

package 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;

@WebServlet("/user/*")//给一个路径信息
public class UserServlet extends BaseServlet {
    protected void add(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("这是UserServlet中的add()方法");
    }
    protected void minus(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("这是userServlet中的minus()方法");
    }
}

CategoryServlet

package 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;

@WebServlet("/category/*")
public class CategoryServlet extends BaseServlet {
    protected void say(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("这是category中的say()方法");
    }
    protected void talk(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("这是userServlet中的minus()方法");
    }
}

再来运行测试一下程序

 

我们还可以调佣category表的相关操作

  

 

 

 上面这个兜底文件的代码还存在一定的问题

在servlet里面,有些方法是不想被比人访问的,如果采用getDeclaredMethod这样来做,所有的相关方法对象都能被获取,然后在暴力破解一下,就能访问

所以改动一下

 获取方法对象的函数就设置成getMethod,只能获取public修饰的方法

然后在相关的servlet页面里面,我们把方法修饰符全部变成public 

这里就不贴代码在这个地方了

下面我们利用上面的方法把项目的页面路径改写一下

怎么改也很简单,把之前做的servlet单独抽成一个方法放在UserServlet里面就行

UserServlet

package web.servlet;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import domain.ResultInfo;
import domain.User;
import org.apache.commons.beanutils.BeanUtils;
import service.UserService;
import service.impl.UserServiceImpl;

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.util.Map;

@WebServlet("/user/*")//给一个路径信息
public class UserServlet extends BaseServlet {
    //每一个方法都需要用到UserService这个业务对象
    private UserService service = new UserServiceImpl();
    private ResultInfo info = new ResultInfo();
    private ObjectMapper objectMapper = new ObjectMapper();
    /**
     *
     * @param request
     * @param response
     */
    public void regist(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //验证校验
        String check = request.getParameter("check");
        //从session中获取验证码
        //这个是做验证码的时候,就给我们放到服务器里面了
        String checkcodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");

        //这里判断一下验证码是否是正确的,如果不正确,直接return结束
        if(checkcodeServer == null || !check.equalsIgnoreCase(checkcodeServer)) {
            //这里验证码错误
            //还是调用一个后端结果信息处理对象
            ResultInfo info = new ResultInfo();
            info.setFlag(false);
            info.setErrorMsg("验证码错误");
            //将resultInfo对象转变为json对象,响应给请求端
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(info);

            //设置响应格式并且传送数据
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(json);
            //让程序在这个位置结束,不往下执行了
            return;
        }
        //获取从前端传过来的数据
        Map<String,String[]> map = request.getParameterMap();
        //把这些集合数据封装成一个对象
        //这里利用BeanUtils工具
        User user = new User();//这个user类之前就已经做好了
        try {
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //内部我们先假定存在一个regist方法
        boolean flag = service.regist(user);
        //响应结果
        //注册成功返回true,失败返回false
        if(flag) {
            //成功
            //成功
            info.setFlag(true);
        } else {
            info.setFlag(false);
            info.setErrorMsg("注册失败了");
        }
        String json = objectMapper.writeValueAsString(info);
        //将json数据写回给客户端
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(json);
    }

    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //先来判断一下验证码是否正确,否则一切不用说了
        //根据前端name属性来获取验证码
        String checkCode = request.getParameter("check");
        //从session中获取验证码
        String checkCodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");
        //需要一个处理信息的对象
        //后面会把这个对象变成json数据格式返回给用户
        response.setContentType("application/json;charset=utf-8");
        //然后来判断一下验证码是否输入正确
        if(checkCode == null || !checkCode.equalsIgnoreCase(checkCodeServer)) {
            //验证码出错,直接在这个里面卡死程序
            info.setFlag(false);
            info.setErrorMsg("验证码错误");
            //变为json数据格式传给客户端
            String json = objectMapper.writeValueAsString(info);
            //回写到客户端里面去
            response.getWriter().write(json);
            return;
        }

        //在把从前端拿到数据变成map集合,然后利用BeanUtils对象进行封装
        Map<String,String[]> map = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        User u = service.login(user);//传入这个对象,然后从数据库中看看有没有这个用户
        //如果查询不到用户
        if(u == null) {
            info.setFlag(false);
            info.setErrorMsg("用户名或者密码错误");
        }

        //另外需要判断的就是用户是否被激活
        if(u != null && !"Y".equals(u.getStatus())) {
            info.setFlag(false);
            info.setErrorMsg("您还没有被激活,请激活");
        }

        //考虑一下登录成功的情况下
        if(u != null && "Y".equals(u.getStatus())) {
            //登录成功,给一个session标志,好追踪
            request.getSession().setAttribute("user",u);
            //返回一个标志true
            //然后返回login.html之后,会跳转到首页
            info.setFlag(true);
        }

        //返回数据
        objectMapper.writeValue(response.getOutputStream(),info);
    }

    public void exit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //销毁session对象
        request.getSession().invalidate();
        //直接重定向页面,注意重定向的路径必须写全
        //直接跳转到登录页面
        response.sendRedirect(request.getContextPath()+"/login.html");
    }

    public void active(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //这里要拿到激活码
        String codeString = request.getParameter("code");
        if (codeString != null) {
            //如果存在用户,然后才来激活
            boolean flag = service.active(codeString);
            String msg = null;
            //根据结果集的结果进行处理
            if (flag) {
                //成功,就提示跳转到登录页面
                msg = "激活成功,请<a href = 'login.html'>登录</a>";
            } else {
                //失败,就提示联系管理员
                msg = "激活失败,请联系管理员";
            }
            //把数据响应给客户端
            response.getWriter().write(msg);//向客户端回写数据
        }
    }

    /**
     * 通过session查询单个对象
     * @param request
     * @param response
     * @throws IOException
     */
    public void findOne(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //拿到存储在服务器的对象的session
        Object user = request.getSession().getAttribute("user");
        response.setContentType("application/json;charset=utf-8");
        objectMapper.writeValue(response.getOutputStream(),user);
    }

}

 把前端一些页面路径也做一些相应的更改

register.html

 

header.html

 

 

 

 login.html

 

 上面路径写错了,/user/login最前面不要加/,我就不重新改动了,另外还需要修改的地方,邮件激活

 

下面测试运行一下

 

把这条数据插入到数据库里面

 查询数据库发现已经插进去了,只是激活状态码还没有修改过来

现在去点击邮件激活

激活成功变成Y了

下面主要做旅游的一些主体功能

 功能1:分类数据展示功能

换句话说,就是上面的的这些功能展示我们要从数据库中获取

这个功能就不是tab_user表的功能了,所以我们不在UserServlet中实现。

那这个功能,重点体现在什么表里

 体现在这个叫tab_category表里面

所以,我们需要做一个 Category的servlet,然后里面写上与这张表相关的方法

那么来说一下,分类数据展示功能的设计原理

先来修改一下BaseServlet页面,这个servlet的兜底页面,里面我们需要添加几个方法进去,原因在于,我们之前在写程序的时候,遇到很多次我们需要把把当前的数据变成json对象,然后返回给前端来使用。也就是如下代码

 这段代码在每一个方法中的复用率太高了,我把他写到BaseServlet里面去,以后所有的servlet都可以去调用这两个方法

 所以,之前在UserServlet中的业务代码就可以进行修改了

这里我是把ObjectMapper对象拿出来了,既然在BaseServlet文件里面有方法了,这些都将可以省略不要了。

直接调用writeValue这个方法就回写了

 修改之后的UserServlet.java页面代码

package web.servlet;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import domain.ResultInfo;
import domain.User;
import org.apache.commons.beanutils.BeanUtils;
import service.UserService;
import service.impl.UserServiceImpl;

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.util.Map;

@WebServlet("/user/*")//给一个路径信息
public class UserServlet extends BaseServlet {
    //每一个方法都需要用到UserService这个业务对象
    private UserService service = new UserServiceImpl();
    private ResultInfo info = new ResultInfo();

    /**
     *
     * @param request
     * @param response
     */
    public void regist(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //验证校验
        String check = request.getParameter("check");
        //从session中获取验证码
        //这个是做验证码的时候,就给我们放到服务器里面了
        String checkcodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");

        //这里判断一下验证码是否是正确的,如果不正确,直接return结束
        if(checkcodeServer == null || !check.equalsIgnoreCase(checkcodeServer)) {
            //这里验证码错误
            //还是调用一个后端结果信息处理对象
            ResultInfo info = new ResultInfo();
            info.setFlag(false);
            info.setErrorMsg("验证码错误");
            //向客户端回写数据
            writeValue(info,response);
            //让程序在这个位置结束,不往下执行了
            return;
        }
        //获取从前端传过来的数据
        Map<String,String[]> map = request.getParameterMap();
        //把这些集合数据封装成一个对象
        //这里利用BeanUtils工具
        User user = new User();//这个user类之前就已经做好了
        try {
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //内部我们先假定存在一个regist方法
        boolean flag = service.regist(user);
        //响应结果
        //注册成功返回true,失败返回false
        if(flag) {
            //成功
            //成功
            info.setFlag(true);
        } else {
            info.setFlag(false);
            info.setErrorMsg("注册失败了");
        }
        String json = writeValueAsString(info);
        //将json数据写回给客户端
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(json);
    }

    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //先来判断一下验证码是否正确,否则一切不用说了
        //根据前端name属性来获取验证码
        String checkCode = request.getParameter("check");
        //从session中获取验证码
        String checkCodeServer = (String)request.getSession().getAttribute("CHECKCODE_SERVER");
        //需要一个处理信息的对象
        //后面会把这个对象变成json数据格式返回给用户
        response.setContentType("application/json;charset=utf-8");
        //然后来判断一下验证码是否输入正确
        if(checkCode == null || !checkCode.equalsIgnoreCase(checkCodeServer)) {
            //验证码出错,直接在这个里面卡死程序
            info.setFlag(false);
            info.setErrorMsg("验证码错误");
           writeValue(info,response);
            return;
        }

        //在把从前端拿到数据变成map集合,然后利用BeanUtils对象进行封装
        Map<String,String[]> map = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        User u = service.login(user);//传入这个对象,然后从数据库中看看有没有这个用户
        //如果查询不到用户
        if(u == null) {
            info.setFlag(false);
            info.setErrorMsg("用户名或者密码错误");
        }

        //另外需要判断的就是用户是否被激活
        if(u != null && !"Y".equals(u.getStatus())) {
            info.setFlag(false);
            info.setErrorMsg("您还没有被激活,请激活");
        }

        //考虑一下登录成功的情况下
        if(u != null && "Y".equals(u.getStatus())) {
            //登录成功,给一个session标志,好追踪
            request.getSession().setAttribute("user",u);
            //返回一个标志true
            //然后返回login.html之后,会跳转到首页
            info.setFlag(true);
        }

        //返回数据
        writeValue(info,response);
    }

    public void exit(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //销毁session对象
        request.getSession().invalidate();
        //直接重定向页面,注意重定向的路径必须写全
        //直接跳转到登录页面
        response.sendRedirect(request.getContextPath()+"/login.html");
    }

    public void active(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //这里要拿到激活码
        String codeString = request.getParameter("code");
        if (codeString != null) {
            //如果存在用户,然后才来激活
            boolean flag = service.active(codeString);
            String msg = null;
            //根据结果集的结果进行处理
            if (flag) {
                //成功,就提示跳转到登录页面
                msg = "激活成功,请<a href = 'login.html'>登录</a>";
            } else {
                //失败,就提示联系管理员
                msg = "激活失败,请联系管理员";
            }
            //把数据响应给客户端
            response.getWriter().write(msg);//向客户端回写数据
        }
    }

    /**
     * 通过session查询单个对象
     * @param request
     * @param response
     * @throws IOException
     */
    public void findOne(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //拿到存储在服务器的对象的session
        Object user = request.getSession().getAttribute("user");
        response.setContentType("application/json;charset=utf-8");
      writeValue(user,response);
    }

}

再来说回正题

先来写CategoryServlet页面、

然后看看CategoryService页面与CategoryServiceImpl页面

 下面再去看dao层的CategoryDao页面与CategoryDaoImpl页面

 然后去修改前台页面header.html

 这个里面的li标签全部都要注释掉

 然后在header.html顶部,页面加载完成后,调用ajax进行异步的请求处理

做好了之后,我们来测试一下

 这里可以自行测试,页面只要只要正常显示,说明你的代码没问题

下面说一个问题,我们每一次去访问这个页面,她都会去dao层访问一个方法findAll

也就是说会不停的去select数据库,但是这部分的数据又不是那种会经常发生变化的,所以,我们在这里对分类数据进行一个缓存优化操作,那么我们这里想到的就是redis缓存数据库

原理也就是说,第一次从数据库拿到数据之后,然后就把数据存储到redis数据库里面

 

 

在CategoryServiceImpl中修改代码

package service.impl;

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

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

public class CategoryServiceImpl implements CategoryService {

    //会去调用dao层中具体的数据库方法
    CategoryDao categoryDao = new CategoryDaoImpl();

    @Override
    public List<Category> findAll() {
        //先从redis中查找数据
        //需要一个redis的连接工具
        Jedis jedis = JedisUtil.getJedis();
        Set<Tuple> res = jedis.zrangeWithScores("category",0,-1);
        List<Category> cs = null;
        //然后来判断这个结果集是否存在
        if(res == null && res.size() == 0) {
            System.out.println("从数据库查询");
            //这种情况数据没有,走数据库查询
            //然后把数据添加到redis数据里面
            cs = categoryDao.findAll();
            //集合对象需要遍历拿出
            for(int i = 0;i < cs.size();i++) {
                //有几条对象插几条进来
                jedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());
            }
        } else {
            System.out.println("从redis中查询");
            cs = new ArrayList<Category>();
            //把set集合中的数据插入到List集合里面,然后返回
            for(Tuple data : res) {
                //Tuple里面有id与name
                Category category = new Category();
                int score = (int)data.getScore();
                String str = data.getElement();
                category.setCid(score);
                category.setCname(str);
                cs.add(category);
            }
        }
        return cs;
    }
}

测试这个代码之前,必须把redis服务器给打开

 

 刚开始redis里面还没有数据,后来运行一下就有了 

并且第一次访问是从数据库查询的

 在把这个页面运行一次

这样就极大减轻了数据库的压力

 下面来做旅游线路的一个分页展示

这里涉及到两张表,一张是旅游线路表tab_route,另外一张是分类表tab_category表

利用sqlyog来看一下两张表之间的关系

把你想要有关系的表,直接拖进来就行了

 直接给我们生成了一个一对多的关系

这个页面的语句大概处理方式就是,根据不同的cid来找不同的路线

select * from tab_route where cid = ?

这些li提交的位置都是route_list.html页面,那么他又是根据cid来区分页面的,所以,我们要子啊route_list.html页面里面获取一下cid这个东西

在js的location对象中有那么一个方法

 获取一个url问号后面的部分

 去访问一下上面这个route_list.html页面

下面来做根据id查询不同类别的旅游线路

分页展示旅游线路数据

我们需要用分页的效果来展示

 

1.创建一下PageBean这个对象 

package domain;

import java.util.List;

/**
 * 分页对象
 */
public class PageBean<T> {

    private int totalCount;//总记录数
    private int totalPage;//总页数
    private int currentPage;//当前页码
    private int pageSize;//每页显示的条数

    private List<T> list;//每页显示的数据集合

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}

 下面开始进行代码编写

1.先来写服务器代码的编写

旅游路线展示的相关操作,是和route表相关的,所以,我们建立的servlet,service,dao都是与这张表相关联的

先来做一个RouteServlet页面

package web.servlet;

import domain.PageBean;
import domain.Route;

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;

@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {

    //这里需要调用service来chauxn
    private RouteService routeService = new RouteServiceImpl();
    /**
     * 分页查询功能
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.接收参数
        String currentPageStr = request.getParameter("currentPage");
        String pageSizeStr = request.getParameter("pageSize");
        String cidStr = request.getParameter("cid");

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

        int currentPage = 1;//当前页面默认为第一页
        if(currentPageStr != null && currentPageStr.length() > 0) {
            currentPage = Integer.parseInt(currentPageStr);
        }

        int pageSize = 5;
        if(pageSizeStr != null && pageSizeStr.length() > 0) {
            pageSize = Integer.parseInt(pageSizeStr);
        }

        //3.调用service查询PageBean对象
        //这个route封装的是一个数据库的查询信息
        PageBean<Route> pb = routeService.pageQuery(cid,currentPage,pageSize);

        //4.将pageBean对象序列化为json数据返回
        writeValue(pb,response);

    }
}

然后去把RouteService与RouteServiceImpl完成

RouteService

package web.servlet;

import domain.PageBean;
import domain.Route;

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;

@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {

    //这里需要调用service来chauxn
    private RouteService routeService = new RouteServiceImpl();
    /**
     * 分页查询功能
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.接收参数
        String currentPageStr = request.getParameter("currentPage");
        String pageSizeStr = request.getParameter("pageSize");
        String cidStr = request.getParameter("cid");

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

        int currentPage = 1;//当前页面默认为第一页
        if(currentPageStr != null && currentPageStr.length() > 0) {
            currentPage = Integer.parseInt(currentPageStr);
        }

        int pageSize = 5;
        if(pageSizeStr != null && pageSizeStr.length() > 0) {
            pageSize = Integer.parseInt(pageSizeStr);
        }

        //3.调用service查询PageBean对象
        //这个route封装的是一个数据库的查询信息
        PageBean<Route> pb = routeService.pageQuery(cid,currentPage,pageSize);

        //4.将pageBean对象序列化为json数据返回
        writeValue(pb,response);

    }
}

RouteServiceImpl

package service.impl;

import domain.PageBean;
import domain.Route;
import service.RouteService;

import java.util.List;

public class RouteServiceImpl implements RouteService {
    //需要一个dao层对象去查找数据库
    private RouteDao routeDao = new RouteDaoImpl();
    @Override
    public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize) {
        PageBean<Route> pb = new PageBean<Route>();
        //考虑一下service层返回什么数据
        //把所有数据集给封装到一个PageBean对象里面
        //设置当前页码
        pb.setCurrentPage(currentPage);
        //设置每页显示条数
        pb.setPageSize(pageSize);

        //得到每个栏目的总记录数
        int totalCount = routeDao.findTotalCount(cid);
        pb.setTotalCount(totalCount);

        //设置当前页面显示的数据集合
        //也就是把一个数据库里面的一个route对象给封装进去
        //这个currentPage是从前端页面传过来的
        int start = (currentPage - 1) * pageSize;
        List<Route> list = routeDao.findByPage(cid,start,pageSize) ;

        //下面设置一下总页数
        //总页数= 总记录数/每页显示的条数 如果除不尽加一页
        int totalPage = totalCount % pageSize == 0 ? totalCount % pageSize : (totalCount / pageSize) + 1;
        pb.setTotalPage(totalPage);

        return pb;
    }
}

上面针对于limit start,end中,start的某个细节进行Fenix

 

下面去实现一下dao层里面的东西

RouteDao

package dao;

import domain.Route;

import java.util.List;

public interface RouteDao {

    int findTotalCount(int cid);

    List<Route> findByPage(int cid, int start, int pageSize);
}

RouteDaoImpl

package dao.impl;

import dao.RouteDao;
import domain.Route;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import util.JDBCUtils;

import java.util.List;

public class RouteDaoImpl implements RouteDao {
    private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());

    //根据某一个分类来查看有多少个数据
    @Override
    public int findTotalCount(int cid) {
        String sql = "select count(*) from tab_route where cid = ?";
        return jdbcTemplate.queryForObject(sql,Integer.class,cid);
    }

    @Override
    public List<Route> findByPage(int cid, int start, int pageSize) {
       String sql = "select * from tab_route where cid = ? limit ?,?";
       return jdbcTemplate.query(sql,new BeanPropertyRowMapper<Route>(Route.class),cid,start,pageSize);
    }

}

上面就是后台代码的实现,下面来做前台代码

route_list.html页面

先来探讨几个问题:

第一个核心查询方法:

 limit后面的第二个问号是要查询几条数据出来,也就是对应的变量是pageSize,那么就有一个问题就是,这个pageSize是从什么地方传进来的? 

因为在进行Ajax请求的时候,我们回去访问/route/*,也就是一个pageQuery方法,这个方法内部会接收三个参数,如下

但是我们在对ajax请求的时候,只传递了两个参数,如下:

那么pageSize从哪里来, 

 在回到我们的RouteServlet里面,我们可以看到对于pageSize这个参数,会给我们设置一个默认值

 所以,我们即使看不到pageSize被传递也是有默认值的

另外再来说一下分页的设计原理

 

下面再来解决数据传输回来data is null的问题

 

其实就是忘了给pb对象设置给list这个属性

 目前来说,在数据库里面只有cid=5这个栏目有数据显示。其他栏目你点进去也是没有数据的

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

初级软件测试工程师工资(薪资待遇)一般是多少?

那接下来&#xff0c;我们要讲的是从软件测试这个岗位与职责&#xff0c;以及对应的标准薪资范畴 到底软件测试它不同的层次它要负责一些什么样的事情&#xff0c;对于软件测试这个岗位呢&#xff0c;第一个&#xff0c;它要求的东西确实非常的多&#xff0c;比如说你要懂数据…

SpringBoot - WebSocket的使用和聊天室练习

SpringBoot - WebSocket的使用和聊天室练习前言一. SpringBoot整合WebSocket1.1 &#xff08;插曲&#xff09;SpringCloud网关服务接入WebSocket启动错误二. 前端代码监听2.1 模拟进入/离开聊天室2.2 模拟聊天前言 近期准备在我的个人云直播项目中&#xff0c;编写弹幕模块。…

超详细的 pytest 教程(一)使用入门篇

前言 pytest到目前为止还没有翻译的比较好全面的使用文档&#xff0c;很多英文不太好的小伙伴&#xff0c;在学习时看英文文档还是很吃力。本来去年就计划写pytest详细的使用文档的&#xff0c;由于时间关系一直搁置&#xff0c;直到今天才开始写。本文是第一篇&#xff0c;主…

基于jsp+mysql+ssm校园在线投票系统-计算机毕业设计

项目介绍 校园在线投票系统主要包括系统用户管理模块、新闻公告管理模块、投票信息管理、班级信息管理、登录模块、和退出模块等多个模块。系统采用了jsp的mvc框架,SSM(springMvcspringMybatis)框架进行开发,本系统是独立的运行&#xff0c;不依附于其他系统&#xff0c;可移植…

Apipost下载安装和功能详解

一、ApiPost简介 ApiPost PostMan Swagger Mock Jmeter 后端、前端、测试同时在线编辑&#xff0c;同时在线协作&#xff0c;内容实时同步 1.官网地址&#xff1a;https://www.apipost.cn/ 2.官网支持客户端下载及web版在线调试&#xff0c;可根据自己的需求选择适合自己的…

@Controller和@RestController的区别?

本文为joshua317原创文章,转载请注明&#xff1a;转载自joshua317博客 Controller和RestController的区别&#xff1f; - joshua317的博客 Controller和RestController的区别&#xff1f; 在springboot开发中控制层使用注解Controller时&#xff0c;加有GetMapping(PostMappi…

网络开关量输入转4G模块钡铼技术S274

网络开关量输入转4G模块钡铼技术S274支持4路DIN4路DO1路RS485&#xff0c;本机设备自带的继电器 DO 寄存器地址属于保持线圈&#xff0c;地址 0-3&#xff0c;服务器主站发送报文格式&#xff1a; 接收设备返回报文格式&#xff1a; 示例&#xff1a;读取2 个DO状态&#xff…

FS5175AE的PCB布局设计建议

FS5175AE的PCB布局设计建议-基础篇 开关电源的一个常见问题是“不稳定”的开关波形。有时,波形抖动很明显,可以听到从磁性元件发出噪声。如果问题与印刷电路板(PCB)布局有关,则很难确定原因。 EMC也是很注重(PCB)布局,这就是为什么在开关电源设计的早期正确布局PCB至关重要的原…

React 学习笔记:事件处理

React 事件处理 React 采用 on 事件名的方式来绑定一个事件&#xff0c;注意&#xff0c;这里和原生的事件是有区别的&#xff0c;原生的事件全是小写 onclick , React 里的事件是驼峰 onClick 。并且 React 中若想阻止默认事件需要显示的调用 e.preventDefault&#xff0c;而…

智工教育:2023年安全工程师考试习题

答案在最后 1.依据中共中央国务院《关于推进安全生产领域改革发展的意见》&#xff0c;到( )年&#xff0c;实现安全生产治理体系和治理能力现代化&#xff0c;全民安全文明素质全面提升&#xff0c;安全生产保障能力显著增强&#xff0c;为实现中华民族伟大复兴的中国梦奠定稳…

Linux系统IO

文章目录Linux系统IOsysio简介sysio版本的copy示例代码代码说明函数讲解如何编译 运行系统IO与标准IO的区别示例代码函数讲解编译 运行&#xff1f;程序中的重定向代码示例代码说明函数讲解编译 运行&#xff1f;代码示例函数讲解编译 运行Linux系统IO sysio简介 所谓文件IO就…

全国青少年软件编程(Scratch)等级考试二级考试真题2022年6月——持续更新.....

电子学会202206Scratch二级真题及参考答案 1.角色初始位置如图所示&#xff0c;下面哪个选项能让角色移到舞台的左下角&#xff1f;&#xff08; &#xff09; A. B. C. D. 正确答案&#xff1a;C 答案解析&#xff1a; 舞台的左下角&#xff0c;坐标x为负数&#xff0c;…

【数据结构】七大排序

目录 一、什么是稳定性 二、七大排序 2.1基于选择的思想 2.1.1直接选择排序 2.1.2堆排序 2.2基于插入的思想 2.2.1直接插入排序 2.2.2希尔排序 2.3归并排序 2.4基于交换的思想 2.4.1冒泡排序 2.4.2快速排序 三、外部排序 排序就是将一组无序的数据经过一定的算法调…

Linux系统:root用户 登录失败

问题 在Linux系统上&#xff0c;从root用户切换到oracle用户时报错 su: cannot open session: Permission denied 如下&#xff1a; 分析 定位原因1 分析登录日志&#xff0c;可以看到时登录的时候limit中的 memlock 设置失败&#xff0c;导致用户登录失败&#xff1a; limi…

[GO] Gin入门

1. Gin基本使用 1.1 Gin入门 Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点对于Golang而言,web框架的依赖要远比Python,Java之类要小,自身的net/http足够简单,性能也非常不错借助框架开发,不仅可以省去很多常用的封装带来的时…

为本地web服务配置使用固定的二级子域名【内网穿透】

由于使用免费的cpolar所生成的公网地址为随机临时地址&#xff0c;该地址24小时内会发生变化&#xff0c;对于需要长期访问的用户来讲比较不方便。 不过我们可以为其配置cpolar固定的二级子域名&#xff08;该二级子域名可自定义&#xff09;&#xff0c;该地址不会随机变化&a…

芯片漫游指南(2)-- UVM结构

目录&#xff1a;1 组件家族1.1概述1.2 uvm_driver1.2.1 概述1.2.2 示例1.3 uvm_monitor1.3.1 概述1.3.2 示例1.4 uvm_sequencer1.4.1 概述1.4.2 示例1.5 uvm_agent1.5.1 概述1.5.2 示例1.6 uvm_scoreboard1.6.1 概述1.6.2 示例1.7 uvm_env1.7.1 概述1.7.2 示例1.8 uvm_test1.8…

天翎携手群晖助力电商行业文档管理

编者按&#xff1a;电商行业的文档管理怎么做&#xff1f;本文根据电商行业文档管理中存在的一些难点&#xff0c;提出天翎文档管理系统和群晖NAS结合的解决方案。 关键词&#xff1a;免安装&#xff0c;免维护&#xff0c;文件分类&#xff0c;权限设置&#xff0c;文件同步&…

【拿捏链表(Ⅱ)】—Leetcode删除排序链表中的重复元素

目录删除排序链表中的重复元素(Ⅰ)删除排序链表中的重复元素(Ⅱ)删除排序链表中的重复元素(Ⅰ) 题目&#xff1a; 给定一个已排序的链表的头 head &#xff0c;删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 思路&#xff1a;这里的思路很简单&…

Navigation--导航算法(局部视野导航)--DWA、TAB

DWA 动态窗口法&#xff08;dynamic window approach&#xff0c;DWA&#xff09;目前与A*一样都是ROS导航包中提供的基本路径规划算法。DWA是一种贪心的算法&#xff0c;通过可选速度、可选角速度的组合&#xff0c;模拟出很多局部轨迹&#xff0c;然后选择最优的。这种方法时…