• Java EE入门(十五)——Servlet&JSP案例(用户信息系统)


    Java EE入门(十五)——Servlet&JSP案例(用户信息系统)
      iwehdio的博客园:https://www.cnblogs.com/iwehdio/

    一、资源跳转

    • 使用绝对路径,先要判断所定义的路径是给谁用。

      • 如果要给客户端浏览器用,就要在其前面加虚拟路径,如浏览器访问、重定向。
      • 如果要给服务器用,则直接写定义的资源路径,如转发。
    • request 是浏览器给服务器的请求,是服务器接收并处理的信息,不需要加虚拟路径。

      • 转发:request.getRequestDispatcher(资源路径).forward(request, response)
      • 转发是在服务器端进行的跳转,可以共享 request 域中的数据。
    • response 是服务器给浏览器的响应,需要浏览器再访问其他资源,因此需要加虚拟路径。。

      • 重定向:response.sendRedirect(虚拟目录 + 资源路径)
      • request 获取虚拟目录:request.getContextPath()
      • 则动态获取虚拟目录:response.sendRedirect(request.getContextPath() + 资源路径)
      • 重定向是在浏览器端进行的跳转,不能共享 request 域中的数据。
    • jsp 页面最后要由浏览器解析,因此需要加虚拟路径。

      • jsp 动态获取虚拟目录:${pageContext.request.contextPath}
    • 转发和重定向的区别:

      • 实际发⽣位置(端)不同,地址栏变换不同。
      • 资源地址用法不同。给服务器⽤的直接从资源名开始写,给浏览器⽤的
        要把应⽤名写上,
      • 能够去往的URL的范围不⼀样。
      • 传递数据的类型不同。转发的request对象可以传递各种类型的数据,包括对象,重定向只能传递字符串。
      • 跳转的时间不同。转发时,执⾏到跳转语句时就会⽴刻跳转。重定向,整个⻚⾯执⾏完之后才执⾏跳转。
    • 什么时候使用转发,什么时候使用重定向?

      • 需要 request 域中数据的时候,必须用请求转发。
      • 需要访问站外资源的时候用重定向。
      • 典型的应⽤场景:
        • 转发: 访问 Servlet 处理业务逻辑,然后转发到 jsp 显示处理结果,浏览器地址栏不变。
        • 重定向: 提交表单,处理成功后重定向到另⼀个 jsp,防⽌表单重复提交,浏览器地址栏变了。
    • 案例中转发与重定向的选择:

      • UserListServlet:查询完所有用户后,需要到 list.jsp 显示查询结果,使用转发。
      • LoginServlet:登录。
        • 验证码错误或密码错误,需要携带错误信息,到 login.jsp 显示处理结果,使用转发。
        • 全部正确登录成功,登录业务处理成功,使用重定向。而且需要把用户信息存入 session 。
      • AddListServlet / DelUserServlet:添加 / 删除用户信息成功后,需要显示更新后用户列表,重定向到 UserListServlet 再转发到 list.jsp 显示查询结果。
      • FindServlet:按 id 查询用户后,需要携带数据到 update.jsp 重显,使用转发。而且作为修改功能的一部分,此次请求还没有被完成,使用转发。
      • UpdateUserServlet:修改用户信息成功后,需要显示更新后用户列表,重定向到 UserListServlet 再转发到 list.jsp 显示查询结果。作为修改功能的一部分,此次请求已经被完成,使用重定向。

    二、标准类封装

    • BeanUtils 工具类:一般用于封装从 request 域中获取的 Map 集合。

      • 使用 Map 集合获取的一般是以 post 方式提交的 form 表单数据。

      • 调用populate(Object obj, Map map)方法,将Map集合中的键值对封装为 JavaBean 中的属性和属性值。

      • 实现:

        //获取request域中的参数,返回Map集合
        Map<String, String[]> map = request.getParameterMap();
        //创建一个空的对象接收
        User loginuser = new User();
        try {
            //按键值对封装
            BeanUtils.populate(loginuser, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        
    • Spring JDBC 下的 JavaBean 对象的封装实现类 RowMapper。

      • 可以使用匿名类自定义,一般使用 BeanPropertyPowMapper实现类自动封装。

      • 一般用于接收 JdbcTemplate.query 方法 / JdbcTemplate.queryForObject 方法返回的结果,将其封装为相应的 JavaBean 对象的数组 / JavaBean 对象,需要传入泛型和字节码对象。

      • 格式为new BeanPropertyRowMapper<类型>(类型.class)

      • 实现:

        //查询id对应的信息
        String sql = "select * from JSP where id = ?";
        return template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
        

    三、用户信息系统案例分析

    • 需求分析:

      • 基础功能:
        • 列表显示。
        • 用户登录。
        • 添加用户信息。
        • 删除单个用户。
        • 修改用户信息。
      • 综合功能:
        • 批量删除选中用户。
        • 分页列表显示。
        • 条件查询。
    • Java 后端项目结构:

    • 三层架构:

      • 表示层:web 包下的 Servlet ,接收前端请求,封装后调用业务逻辑层。完成后转发到 jsp 页面显示。
      • 业务逻辑层:
        • UserService 接口:定义业务逻辑层的功能与传入传出参数类型。
        • UserServiceImpl 实现类:组合数据访问层中的底层数据操作方法,完成表示层要求的复杂功能。
      • 数据访问层:
        • UserDao 接口:定义数据访问层的功能与传入传出参数类型。
        • UserDaoImpl 实现类:定义了对数据库最基础的增删改查操作。
    • 项目总体结构:

      • Java 后端项目结构:
        • src / cn.iwehdio 。
        • druid.properties 配置文件。
      • Web 前端项目结构:
        • css / js / fonts:BootStrap、JQuery 相关依赖。
        • WEB-INF / lib:数据库、Servlet 相关依赖 jar 包。
        • index.jsp:项目初始页面。
        • list.jsp:列表显示页面。
        • login.jsp:登录页面。
        • add.jsp:添加用户信息页面。
        • update.jsp:修改用户信息页面。
    • 表示层 Servlet 编写流程:

      1. 如果是 post 请求方式,设置编码字符集。
      2. 使用 request 下的 .getParameter 方法获取单个参数,使用 .getParameterMap 方法按键值对 (form表单中的 name : value 对) 获取多个参数。
      3. 判断输入参数的合法性,处理空指针异常。
      4. 如果获取到参数为已有的对象,可以用 BeanUtils.populate(类, map)封装为对象。
      5. 创建业务逻辑层接口引用下的实现类对象:UserService service = new UserServiceImpl()
      6. 对获取的参数进行处理,并调用 service 下的方法实现业务逻辑。
      7. 如果有需要存储的返回的数据,根据其性质存储到 request 域request.setAttribute(),或 session 域session.setAttribute()
      8. 根据需求,转发或重定向到 jsp 页面或其他 Servlet 。
    • 业务逻辑层 service 编写流程:

      1. 创建成员变量,数据操作层对象:private UserDao dao = new UserDaoImpl()
      2. 重写接口中定义的方法。
      3. 处理参数的异常或空指针情况。
      4. 对表示层 Servlet 的输入进行处理,使其符合数据操作层的底层接口定义。
      5. 如果需要输出,对数据操作层 Dao 的输出进行处理,使其符合表示层 Servlet 的接收形式。
    • 数据操作层 dao 编写流程:

      1. 创建成员变量,Jdbc 工具类对象:private JdbcTemplate template = new JdbcTemplate((JDBCUtils.getDataSource()))
      2. 重写接口中定义的方法。
      3. 定义初始 SQL 语句。
      4. 根据输入,对 SQL 语句进行拼接和赋值。
      5. 使用 Jdbc 工具类下的方法进行查询。
    • 创建数据库:

      USE db1;
      CREATE TABLE jsp(
        id INT PRIMARY KEY AUTO_INCREMENT,
        NAME VARCHAR(20) NOT NULL,
        gender VARCHAR(5),
        age INT,
        qq VARCHAR(20),
        email VARCHAR(50)
      );
      

    四、基础功能实现

    • 列表显示:

      • 创建 User 对象:

        public class User {
            private int id;
            private String name;
            private String gender;
            private int age;
            private String qq;
            private String email;
            private String username;
            private String password;
            /*
            	set / get / toString 方法
            */
        }
        
      • UserListServlet:

        1. 没有传入的参数。
        2. 使用service.findAll()方法获取数据库中的所有用户,并将结果存入 request。
        3. 转发到 list.jsp 。
        @WebServlet("/userListServlet")
        public class UserListServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                UserService service = new UserServiceImpl();
                List<User> users = service.findAll();
                request.setAttribute("users", users);
                request.getRequestDispatcher("/list.jsp").forward(request,response);
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        @Override
        public List<User> findAll() {
            return dao.findAll();
        }
        
      • UserDaoImpl:

        @Override
        public List<User> findAll() {
            String sql = "select * from jsp";
            List<User> users = template.query(sql, new BeanPropertyRowMapper<User>(User.class));
            return users;
        }
        
      • index.jsp:

        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
          <meta charset="utf-8"/>
          <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
          <meta name="viewport" content="width=device-width, initial-scale=1"/>
          <title>首页</title>
          <link href="css/bootstrap.min.css" rel="stylesheet">
          <script src="js/jquery-2.1.0.min.js"></script>
          <script src="js/bootstrap.min.js"></script>
          <script type="text/javascript">
          </script>
        </head>
        <body>
          <div>
            <h2 style="margin-left: 50px">${sessionScope.user.username}</h2>
          </div>
          <div align="center">
            <a href="${pageContext.request.contextPath}/pageListServlet" style="text-decoration:none;font-size:33px">查询所有用户信息
            </a>
          </div>
        </body>
        </html>
        

    • 用户登录:

      • LoginServlet:

        1. 获取填写到文本框中的验证码。
        2. 从 session 中获取 CheckCodeServlet 生成的验证码并进行比对。
        3. 验证码比对失败则直接存入错误信息并转发到登录页面。
        4. 验证码比对成功则获取账号密码参数。
        5. 使用service.login()方法获取账号密码匹配的用户信息。
        6. 如果匹配得到,则重定向到初始页面 index.jsp 。
        7. 如果匹配不到,则存入错误信息并转发到登录页面。
        @WebServlet("/loginServlet")
        public class LoginServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                request.setCharacterEncoding("utf-8");
                String verifycode = request.getParameter("verifycode");
        
                HttpSession session = request.getSession();
                String server_checkcode = (String)session.getAttribute("CHECKCODE_SERVER");
                session.removeAttribute("CHECKCODE_SERVER");
        
                if(!server_checkcode.equalsIgnoreCase(verifycode)){
        
                    request.setAttribute("login_msg", "验证码错误");
                    request.getRequestDispatcher("/login.jsp").forward(request, response);
                    return;
                }
        
                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();
                }
        
                UserService service = new UserServiceImpl();
                User loginUser = service.login(user);
                if(loginUser != null){
                    session.setAttribute("user", loginUser);
                    response.sendRedirect(request.getContextPath() + "/index.jsp");
                } else {
                    request.setAttribute("login_msg", "用户名密码错误");
                    request.getRequestDispatcher("/login.jsp").forward(request, response);
                }
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        @Override
        public User login(User user) {
            return dao.checkNameAndPassword(user.getUsername(), user.getPassword());
        }
        
      • UserDaoImpl:

        @Override
        public User checkNameAndPassword(String username, String password) {
            try {
                String sql = "select * from JSP where username = ? and password = ?";
                User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
                return user;
            } catch (Exception e){
                e.printStackTrace();
                return null;
            }
        }
        

    • 添加用户信息:

      • AddListServlet:

        1. list.jsp 页面下点击添加,进入 add.jsp ,在此页面下再点击提交,调用 addListServlet 。
        2. 使用 map 集合获取填写的用户信息并封装为 JavaBean 。
        3. 调用service.addUser()方法添加用户信息。
        4. 重定向到 UserListServlet 显示添加结果。
        @WebServlet("/addListServlet")
        public class AddListServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                request.setCharacterEncoding("utf-8");
        
                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();
                }
        
                UserService service = new UserServiceImpl();
                service.addUser(user);
        
                response.sendRedirect(request.getContextPath() + "/pageListServlet");
            }
        
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        @Override
        public void addUser(User user) {
            dao.add(user);
        }
        
      • UserDaoImpl:

        @Override
        public void add(User user) {
            String sql = "insert into JSP values(null, ?, ?, ?, ?, ?, null, null)";
            template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getQq(), user.getEmail());
        }
        
      • add.jsp

        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <!-- HTML5文档-->
        <!DOCTYPE html>
        <!-- 网页使用的语言 -->
        <html lang="zh-CN">
        <head>
            <!-- 指定字符集 -->
            <meta charset="utf-8">
            <!-- 使用Edge最新的浏览器的渲染方式 -->
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <!-- viewport视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
             默认宽度与设备的宽度相同
            initial-scale: 初始的缩放比,为1:1 -->
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
            <title>添加用户</title>
        
            <!-- 1. 导入CSS的全局样式 -->
            <link href="css/bootstrap.min.css" rel="stylesheet">
            <!-- 2. jQuery导入,建议使用1.9以上的版本 -->
            <script src="js/jquery-2.1.0.min.js"></script>
            <!-- 3. 导入bootstrap的js文件 -->
            <script src="js/bootstrap.min.js"></script>
        </head>
        <body>
        <div class="container">
            <center><h3>添加联系人页面</h3></center>
            <form action="${pageContext.request.contextPath}/addListServlet" method="post">
                <div class="form-group">
                    <label for="name">姓名:</label>
                    <input type="text" class="form-control" id="name" name="name" placeholder="请输入姓名">
                </div>
        
                <div class="form-group">
                    <label>性别:</label>
                    <input type="radio" name="gender" value="男" checked="checked"/>男
                    <input type="radio" name="gender" value="女"/>女
                </div>
        
                <div class="form-group">
                    <label for="age">年龄:</label>
                    <input type="text" class="form-control" id="age" name="age" placeholder="请输入年龄">
                </div>
        
                <div class="form-group">
                    <label for="qqnumber">QQ:</label>
                    <input type="text" class="form-control" name="qq" id="qqnumber" placeholder="请输入QQ号码"/>
                </div>
        
                <div class="form-group">
                    <label for="email">Email:</label>
                    <input type="text" class="form-control" name="email" id="email" placeholder="请输入邮箱地址"/>
                </div>
        
                <div class="form-group" style="text-align: center">
                    <input class="btn btn-primary" type="submit" value="提交" />
                    <input class="btn btn-default" type="reset" value="重置" />
                    <input class="btn btn-default" type="button" value="返回" />
                </div>
            </form>
        </div>
        </body>
        </html>
        

    • 删除单个用户:

      • DelUserServlet:

        1. 获取所要删除的用户的 id。
        2. 使用service.delUserById()方法删除用户信息。
        3. 重定向到 UserListServlet 显示删除结果。
        @WebServlet("/delUserServlet")
        public class DelUserServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                String id = request.getParameter("id");
                UserService service = new UserServiceImpl();
                service.delUserById(id);
                response.sendRedirect(request.getContextPath() + "/pageListServlet");
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        • 注意将传入的 String 类型参数转换为 int 类型。
        @Override
        public void delUserById(String id) {
            dao.delete(Integer.parseInt(id));
        }
        
      • UserDaoImpl:

        @Override
        public void delete(int id) {
            String sql = "delete from JSP where id = ?";
            template.update(sql, id);
        }
        
      • 删除按钮操作:

        <!-- HTML中的删除按钮 -->
        <a class="btn btn-default btn-sm" href="javascript:deleteUser(${i.id})">删除</a>
        
        <!-- JS中绑定按钮并提示 -->
        <script>
                function deleteUser(id) {
                    if(confirm("确认删除?")){
                        location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id;
                    }
                }
        </script>
        

    • 修改用户信息:

      • FindServlet / UpdateServlet:

        1. list.jsp 页面下点击修改,调用 FindServlet 。找到对于用户信息后,转发 update.jsp ,在此页面下再点击提交,调用 UpdateServlet 。
        2. FindServlet ,调用service.findUserById()方法寻找用户信息,转发到 update.jsp。
        3. 将用户信息重显,按下提交到 UpdateServlet。
        4. UpdateServlet ,使用 map 集合获取填写的用户信息并封装为 JavaBean 。
        5. 调用service.update()方法添加用户信息。
        6. 重定向到 UserListServlet 显示添加结果。
        @WebServlet("/findServlet")
        public class FindServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                String id = request.getParameter("id");
        
                UserService service = new UserServiceImpl();
                User user = service.findUserById(id);
        
                request.setAttribute("user", user);
                request.getRequestDispatcher("/update.jsp").forward(request, response);
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
        @WebServlet("/updateServlet")
        public class UpdateServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                request.setCharacterEncoding("utf-8");
                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();
                }
        
                UserService service = new UserServiceImpl();
                service.update(user);
        
                response.sendRedirect(request.getContextPath() + "/pageListServlet");
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        @Override
        public User findUserById(String id) {
            return dao.findById(Integer.parseInt(id));
        }
        
        @Override
        public void update(User user) {
            dao.update(user);
        }
        
      • UserDaoImpl:

        @Override
        public User findById(int id) {
            String sql = "select * from JSP where id = ?";
            return template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), id);
        }
        
        @Override
        public void update(User user) {
            String sql = "update JSP set name = ?, gender = ?, age = ?, qq = ?, email = ? where id = ?";
            template.update(sql, user.getName(), user.getGender(), user.getAge(), user.getQq(), user.getEmail(), user.getId());
        }
        
      • update.jsp:

        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>修改用户</title>
            <link href="css/bootstrap.min.css" rel="stylesheet">
            <script src="js/jquery-2.1.0.min.js"></script>
            <script src="js/bootstrap.min.js"></script>
        </head>
        <body>
        <div class="container" style=" 400px;">
            <h3 style="text-align: center;">修改联系人</h3>
            <form action="${pageContext.request.contextPath}/updateServlet" method="post">
                <input type="hidden" name="id" value="${user.id}">
                <div class="form-group">
                    <label for="name">姓名:</label>
                    <input type="text" class="form-control" id="name" name="name"  value="${user.name}" readonly="readonly" placeholder="请输入姓名" />
                </div>
                <div class="form-group">
                    <label>性别:</label>
                    <c:if test="${user.gender=='男'}">
                        <input type="radio" name="gender" value="男"  checked/>男
                        <input type="radio" name="gender" value="女"  />女
                    </c:if>
                    <c:if test="${user.gender=='女'}">
                        <input type="radio" name="gender" value="男"  />男
                        <input type="radio" name="gender" value="女"  checked/>女
                    </c:if>
                </div>
                <div class="form-group">
                    <label for="age">年龄:</label>
                    <input type="text" class="form-control" id="age"  name="age"  value="${user.age}" placeholder="请输入年龄" />
                </div>
                <div class="form-group">
                    <label for="qq">QQ:</label>
                    <input type="text" class="form-control" name="qq" id="qq"  value="${user.qq}" placeholder="请输入QQ号码"/>
                </div>
                <div class="form-group">
                    <label for="email">Email:</label>
                    <input type="text" class="form-control" name="email" id="email"  value="${user.email}" placeholder="请输入邮箱地址"/>
                </div>
                <div class="form-group" style="text-align: center">
                    <input class="btn btn-primary" type="submit" value="提交" />
                    <input class="btn btn-default" type="reset" value="重置" />
                    <input class="btn btn-default" type="button" value="返回"/>
                </div>
            </form>
        </div>
        </body>
        </html>
        

    五、综合功能实现

    • 批量删除选中用户:

      • DelSelectServlet:

        1. list.jsp 中删除选中按钮提交。
        2. 使用.getParameterValues()方法获取所有被选中的用户。
        3. 使用service.delSelect()方法删除选中的用户。
        4. 重定向到 UserListServlet 显示删除后的结果。
        @WebServlet("/delSelectServlet")
        public class DelSelectServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                request.setCharacterEncoding("utf-8");
        
                String[] ids = request.getParameterValues("uid");
        
                UserService service = new UserServiceImpl();
                service.delSelect(ids);
        
                response.sendRedirect(request.getContextPath() + "/pageListServlet");
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        @Override
        public void delSelect(String[] ids) {
            for (String id: ids) {
                dao.delete(Integer.parseInt(id));
            }
        }
        
      • list.jsp 中的全选和提示:

        <!-- 删除选中按钮 -->
        <a class="btn btn-primary" href="javascript:void(0)" id="delSelect">删除选中</a>
        
        <!-- 全选和提示 -->
        <script>
                window.onload = function () {
                    document.getElementById("delSelect").onclick = function () {
                        if(confirm("确认删除选中?"))
                            document.getElementById("tableForm").submit();
                    }
                    document.getElementById("AllCb").onclick = function () {
                        var Cbs = document.getElementsByName("uid");
                        for(var i=0; i<Cbs.length; i++){
                            Cbs[i].checked = this.checked;
                        }
                    }
                }
        </script>
        
      • 更进一步,如何实现在分页后实现跨页的选中删除?


    • 分页列表显示:

      • 前端:分页条的样式,选中和禁用。

      • 封装 Page 对象:

        • 包括当前页码、每页显示条目数、总页码、总条目数和当前页面所要显示的用户信息列表。
        public class Page<T> {
            private int currentPage;
            private int rows;
            private int totalPage;
            private int totalCount;
            private List<T> list;
            /*
            	set / get / toString 方法
            */
        }
        
      • PageListServlet:

        1. 获取当前页码和每页条目数。
        2. 处理传入的页码不合法和每页条目数缺省的情况。
        3. 使用service.listByPage()方法,按当前页码和每页条目数获取 Page 对象。
        4. 将 Page 对象存入 request 域中,转发到 list.jsp。
        @WebServlet("/pageListServlet")
        public class PageListServlet extends HttpServlet {
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                request.setCharacterEncoding("utf-8");
                String currentPage = request.getParameter("currentPage");
                String rows = request.getParameter("rows");
                Map<String ,String[]> condition = request.getParameterMap();
        
                if(currentPage == null || "".equals(currentPage)){
                    currentPage = "1";
                }
                if(rows == null || "".equals(rows)){
                    rows = "5";
                }
                UserService service = new UserServiceImpl();
                Page<User> page = service.listByPage(currentPage, rows, condition);
        
                request.setAttribute("page", page);
                request.setAttribute("condition", condition);
        
                request.getRequestDispatcher("/list.jsp").forward(request, response);
            }
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doPost(request, response);
            }
        }
        
      • UserServiceImpl:

        • 使用 .getCount()方法获取总条目数。
        • 使用.findByPage()方法获取当前页的用户信息。
        @Override
        public Page<User> listByPage(String _currentPage, String _rows, Map<String, String[]> condition) {
        
            Page<User> page = new Page<User>();
            int currentPage = Integer.parseInt(_currentPage);
            int rows = Integer.parseInt(_rows);
            int totalCount = dao.getCount(condition);
            int totalPage = (totalCount % rows) == 0 ? totalCount / rows : totalCount / rows + 1;
        
            if(currentPage < 1 ){
                currentPage = 1;
            } else if(currentPage > totalPage){
                currentPage = totalPage;
            }
        
            List<User> list = dao.findByPage((currentPage-1)*rows, rows, condition);
            page.setCurrentPage(currentPage);
            page.setRows(rows);
            page.setTotalCount(totalCount);
            page.setList(list);
            page.setTotalPage(totalPage);
        
            return page;
        }
        
      • UserDaoImpl:

        • 聚合函数和分页查询。
        @Override
        public int getCount(Map<String, String[]> condition) {
            String sql = "select count(*) from JSP where 1=1 ";
            StringBuilder sb = new StringBuilder(sql);
            Set<String> keys = condition.keySet();
            List<Object> param = new ArrayList<Object>();
            for (String key : keys) {
                if ("currentPage".equals(key) || "rows".equals(key)){
                    continue;
                }
                String value = condition.get(key)[0];
                if(value != null && !"".equals(value)) {
                    sb.append(" and " + key + " like ?");
                    param.add("%" + value + "%");
                }
            }
            sql = sb.toString();
            return template.queryForObject(sql, Integer.class, param.toArray());
        }
        
        @Override
        public List<User> findByPage(int i, int rows, Map<String, String[]> condition) {
            String sql = "select * from JSP where 1=1 ";
            StringBuilder sb = new StringBuilder(sql);
            Set<String> keys = condition.keySet();
            List<Object> param = new ArrayList<Object>();
            for (String key : keys) {
                if ("currentPage".equals(key) || "rows".equals(key)){
                    continue;
                }
                String value = condition.get(key)[0];
                if(value != null && !"".equals(value)) {
                    sb.append(" and " + key + " like ?");
                    param.add("%" + value + "%");
                }
            }
        
            sb.append(" limit ?, ?");
            param.add(i);
            param.add(rows);
            sql = sb.toString();
            return template.query(sql, new BeanPropertyRowMapper<User>(User.class), param.toArray());
        }
        
      • list.jsp 中的分页条:

        <div>
                <nav aria-label="Page navigation">
                    <ul class="pagination">
                        <c:if test="${requestScope.page.currentPage==1}">
                            <li class="disabled">
                        </c:if>
                        <c:if test="${requestScope.page.currentPage!=1}">
                            <li>
                        </c:if>
                            <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage-1}&rows=5" aria-label="Previous">
                                <span aria-hidden="true">&laquo;</span>
                            </a>
                        </li>
                        <c:forEach begin="1" end="${requestScope.page.totalPage}" var="i">
                            <c:if test="${requestScope.page.currentPage==i}">
                                <li class="active"><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5">${i}</a></li>
                            </c:if>
                            <c:if test="${requestScope.page.currentPage!=i}">
                                <li><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5">${i}</a></li>
                            </c:if>
                        </c:forEach>
        
                        <c:if test="${requestScope.page.currentPage==requestScope.page.totalPage}">
                            <li class="disabled">
                        </c:if>
                        <c:if test="${requestScope.page.currentPage!=requestScope.page.totalPage}">
                            <li>
                        </c:if>
                            <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage+1}&rows=5" aria-label="Next">
                                <span aria-hidden="true">&raquo;</span>
                            </a>
                        </li>
                        <span style="font-size:25px;margin: 15px">
                            共${requestScope.page.totalCount}项,第${requestScope.page.currentPage}页
                        </span>
                    </ul>
                </nav>
        </div>
        

    • 条件查询:

      • PageListServlet 改造:

        1. list.jsp 中搜索按钮提交表单。
      1. 获取提交的参数 map 为 condition。
      2. 改造service.listByPage()方法,增加 condition 为参数。
      • UserServiceImpl:

        • 改造 .getCount()方法和.findByPage()方法,增加 condition 为参数。
      • UserDaoImpl:

        • 对传入的 condition 进行条件模糊查询。
      • list.jsp 完整:

        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
        <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>用户信息管理系统</title>
            <link href="css/bootstrap.min.css" rel="stylesheet">
            <script src="js/jquery-2.1.0.min.js"></script>
            <script src="js/bootstrap.min.js"></script>
            <style type="text/css">
                td, th {
                    text-align: center;
                }
            </style>
            <script>
                function deleteUser(id) {
                    if(confirm("确认删除?")){
                        location.href = "${pageContext.request.contextPath}/delUserServlet?id=" + id;
                    }
                }
                window.onload = function () {
                    document.getElementById("delSelect").onclick = function () {
                        if(confirm("确认删除选中?"))
                            document.getElementById("tableForm").submit();
                    }
                    document.getElementById("AllCb").onclick = function () {
                        var Cbs = document.getElementsByName("uid");
                        for(var i=0; i<Cbs.length; i++){
                            Cbs[i].checked = this.checked;
                        }
                    }
                }
            </script>
        </head>
        <body>
        <div class="container">
            <h3 style="text-align: center">用户信息列表</h3>
            <div style="float: left">
                <form action="${pageContext.request.contextPath}/pageListServlet" class="form-inline" method="post">
                    <div class="form-group">
                        <label for="InputName">姓名</label>
                        <input type="text" class="form-control" value="${requestScope.condition.name[0]}" name="name" id="InputName" >
                    </div>
                    <div class="form-group">
                        <label for="InputGender">性别</label>
                        <input type="text" class="form-control" value="${requestScope.condition.gender[0]}" name="gender" id="InputGender">
                    </div>
                    <div class="form-group">
                        <label for="InputAge">年龄</label>
                        <input type="text" class="form-control" value="${requestScope.condition.age[0]}" name="age" id="InputAge">
                    </div>
                    <button type="submit" class="btn btn-default">搜索</button>
                </form>
            </div>
            <div style="float: right;margin: 5px">
                <a class="btn btn-primary" href="${pageContext.request.contextPath}/add.jsp">添加联系人</a>
                <a class="btn btn-primary" href="javascript:void(0)" id="delSelect">删除选中</a>
            </div>
            <form action="${pageContext.request.contextPath}/delSelectServlet" id="tableForm">
                <table border="1" class="table table-bordered table-hover">
                    <tr class="success">
                        <th><input type="checkbox" id="AllCb"></th>
                        <th>编号</th>
                        <th>姓名</th>
                        <th>性别</th>
                        <th>年龄</th>
                        <th>QQ</th>
                        <th>邮箱</th>
                        <th>操作</th>
                    </tr>
                    <c:forEach items="${requestScope.page.list}" var="i" varStatus="s">
                        <tr>
                            <th><input type="checkbox" name="uid" value="${i.id}"></th>
                            <td>${s.count}</td>
                            <td>${i.name}</td>
                            <td>${i.gender}</td>
                            <td>${i.age}</td>
                            <td>${i.qq}</td>
                            <td>${i.email}</td>
                            <td>
                                <a class="btn btn-default btn-sm" href="${pageContext.request.contextPath}/findServlet?id=${i.id}">修改</a>&nbsp;
                                <a class="btn btn-default btn-sm" href="javascript:deleteUser(${i.id})">删除</a>
                            </td>
                        </tr>
                    </c:forEach>
                </table>
            </form>
            <div>
                <nav aria-label="Page navigation">
                    <ul class="pagination">
                        <c:if test="${requestScope.page.currentPage==1}">
                            <li class="disabled">
                        </c:if>
                        <c:if test="${requestScope.page.currentPage!=1}">
                            <li>
                        </c:if>
                            <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage-1}&rows=5&name=${requestScope.
                            condition.name[0]}&age=${requestScope.condition.age[0]}&gender=${requestScope.condition.gender[0]}" aria-label="Previous">
                                <span aria-hidden="true">&laquo;</span>
                            </a>
                        </li>
                        <c:forEach begin="1" end="${requestScope.page.totalPage}" var="i">
                            <c:if test="${requestScope.page.currentPage==i}">
                                <li class="active"><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5&name=${requestScope.
                                condition.name[0]}&age=${requestScope.condition.age[0]}&gender=${requestScope.condition.gender[0]}">${i}</a></li>
                            </c:if>
                            <c:if test="${requestScope.page.currentPage!=i}">
                                <li><a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${i}&rows=5&name=${requestScope.
                                condition.name[0]}&age=${requestScope.condition.age[0]}&gender=${requestScope.condition.gender[0]}">${i}</a></li>
                            </c:if>
                        </c:forEach>
        
                        <c:if test="${requestScope.page.currentPage==requestScope.page.totalPage}">
                            <li class="disabled">
                        </c:if>
                        <c:if test="${requestScope.page.currentPage!=requestScope.page.totalPage}">
                            <li>
                        </c:if>
                            <a href="${pageContext.request.contextPath}/pageListServlet?currentPage=${requestScope.page.currentPage+1}&rows=5&name=${requestScope.
                            condition.name[0]}&age=${requestScope.conditon.age[0]}&gender=${requestScope.condition.gender[0]}" aria-label="Next">
                                <span aria-hidden="true">&raquo;</span>
                            </a>
                        </li>
                        <span style="font-size:25px;margin: 15px">
                            共${requestScope.page.totalCount}项,第${requestScope.page.currentPage}页
                        </span>
                    </ul>
                </nav>
            </div>
        </div>
        </body>
        </html>
        

    iwehdio的博客园:[https://www.cnblogs.com/iwehdio/](https://www.cnblogs.com/iwehdio/)
  • 相关阅读:
    性能优化汇总
    数组迭代,对象迭代
    数据类型转换
    Vue v-model原理解析
    闭包机制及浏览器垃圾回收处理
    面试题解析
    作用域链查找机制,浏览器的垃圾回收机制
    函数的创建与执行,执行函数
    Mybatis底层源码执行流程
    简单易懂的TCP三次握手及四次挥手
  • 原文地址:https://www.cnblogs.com/iwehdio/p/12506535.html
Copyright © 2020-2023  润新知