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视口:网页可以根据设置的宽度自动进行适配,在浏览器的内部虚拟一个容器,容器的宽度与设备的宽度相同。
          width: 默认宽度与设备的宽度相同
          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="width: 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/

猜你喜欢

转载自www.cnblogs.com/iwehdio/p/12506535.html