天天看點

SpringMVC+Spring+MyBatis 的綜合練習 13 (前端頁面之員工清單)

最初的功能不用太複雜,單純展示員工和部門清單,實作翻頁功能。為了能比較和練習,同時實作員工清單和部門清單,分别采用了不同的實作方式。在頁面設計上均使用了 Bootstrap 架構,引入了 JSTL 表達式等。

13.1 Bootstrap 的引入

本來沒啥好說的,又不打算專門寫關于 Bootstrap 的章節,是以就利用頁面搭建的過程中穿插總結一下。

注意:必須引入jQuery,而且還要在 Bootstrap 的引入之前。

方式一:通過CDN引入

在 Bootstrap 的中文官網上,可以找到 Bootstrap 中文網聯合又拍雲存儲共同推出的開放 CDN 服務 - BootCDN 的連結,對廣泛的前端開源庫提供了穩定的存儲和帶寬的支援,例如 Bootstrap、jQuery 等。找到 Bootstrap 和 jQuery 的連結(導航上也有對應的按鈕)會打開相應的界面,羅列着各個版本的CDN,點選【複制 < script > 标簽】即可複制到剪貼闆,然後直接粘貼到 jsp 檔案中 head 标簽中的 meta 标簽後面。下面是個引入的例子。

<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
           

這樣引入後,隻要 Tomcat 伺服器是聯網的,就能正确在頁面展示 Bootstrap 的樣式。

方式二:使用本地檔案

先将 Bootstrap 和 jQuery 的檔案下載下傳到本地,參見前文中的目錄結構,然後直接引用本地檔案。為了建構路徑的友善,先設定一個 APP_PATH 屬性供後面引用檔案時使用,同時該屬性也能用于發起請求。代碼如下:

<%
    pageContext.setAttribute("APP_PATH", request.getContextPath());
%>
<link rel="stylesheet" href="${APP_PATH }/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="${APP_PATH }/static/js/jquery-1.12.4.min.js"></script>
<script src="${APP_PATH }/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
           

這種方式不需要聯網,單機練習比較好用。

13.2 首頁(index.jsp)

這裡就放了兩個連結,向背景發 get 請求,對應的 Controller 攔截後處理,再将結果傳回到前台。代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!-- 引入JSTL -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%
    pageContext.setAttribute("APP_PATH", request.getContextPath());
%>
<link rel="stylesheet" href="${APP_PATH }/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="${APP_PATH }/static/js/jquery-1.12.4.min.js"></script>
<script src="${APP_PATH }/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>

<title>SSM Practice </title>
</head>

<body>
    <!-- 下面是使用 Bootstrap 的開始,所有的内容都要在這個類為 container 的 div 下面 -->
    <div class="container">
        <h1 class="page-header"><a href="${APP_PATH }/employees">員工管理</a></h1>
        <h1 class="page-header"><a href="${APP_PATH }/department.jsp">部門管理</a></h1>
    </div>
</body>

</html>
           

可以看出兩個請求是不一樣的,

  • 員工請求是直接發的
  • 部門請求是轉向了另一個 jsp 檔案,後面詳細說。

13.3 員工清單

首頁發的 /employees 請求後,Controller 攔截到請求開始處理(代碼),轉發到 /WEB-INF/view/employees.jsp 頁面,在 Request 域中封裝了 PageInfo 對象,儲存了查詢結果(list)和分頁資訊。頁面代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 引入JSTL -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<%
    pageContext.setAttribute("APP_PATH", request.getContextPath());
%>
<link rel="stylesheet"
    href="${APP_PATH }/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="${APP_PATH }/static/js/jquery-1.12.4.min.js"></script>
<script
    src="${APP_PATH }/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<title>員工清單</title>

</head>

<body>
  <div class="container">
    <h1 class="page-header">員工管理</h1>
      <div class="row">
        <h3 class="page-header col-md-10">員工清單</h3>
        <button class="page-header col-sd-1 btn btn-info">
          <span class="glyphicon glyphicon-plus"></span> 新增
        </button>
        <button class="page-header col-sd-1 btn btn-danger">
          <span class="glyphicon glyphicon-trash"></span> 删除
        </button>
      </div>

      <br>
      <div class="row">
        <table class="table table-striped table-hover">
          <thead>
            <tr>
              <th class="col-md-1">#</th>
              <th class="col-md-1">部門名稱</th>
              <th class="col-md-1">員工姓名</th>
              <th class="col-md-1">性别</th>
              <th class="col-md-2">電子郵箱</th>
              <th class="col-md-2">建立時間</th>
              <th class="col-md-2">更新時間</th>
              <th class="col-md-2">操作</th>
            </tr>
          </thead>
          <tbody>
            <c:forEach items="${pageInfo.list }" var="employee">
              <tr>
                <td class="col-md-1" style="vertical-align: middle;">${employee.employeeId }</td>
                <td class="col-md-1" style="vertical-align: middle;">${employee.department.departmentName }</td>
                <td class="col-md-1" style="vertical-align: middle;">${employee.employeeName }</td>
                <td class="col-md-1" style="vertical-align: middle;">${employee.employeeGender }</td>
                <td class="col-md-2" style="vertical-align: middle;">${employee.employeeEmail }</td>
                <td class="col-md-2" style="vertical-align: middle;"><fmt:formatDate
                                    value="${employee.gmtCreate }" pattern="yyyy-MM-dd" /></td>
                <td class="col-md-2" style="vertical-align: middle;"><fmt:formatDate
                                    value="${employee.gmtModified }" pattern="yyyy-MM-dd" /></td>
                <td class="col-md-2" style="vertical-align: middle;">
                  <button class="btn btn-primary btn-xs">
                    <span class="glyphicon glyphicon-pencil"></span> 編輯
                  </button>
                  <button class="btn btn-danger btn-xs">
                    <span class="glyphicon glyphicon-trash"></span> 删除
                  </button>
                </td>
              </tr>
            </c:forEach>

              <tr>
                <td style="vertical-align: middle;" colspan="5" class="col-md-6">目前
                            第 ${pageInfo.pageNum } 頁,共 ${pageInfo.pages } 頁,共有
                            ${pageInfo.total } 條記錄。</td>
                <td style="vertical-align: middle;" colspan="3" class="col-md-6"
                            align="right">
                  <nav aria-label="Page navigation">
                    <ul class="pagination pagination">
                        <li><a href="${APP_PATH }/employees?pageNum=1">首頁</a></li>
                      <c:if test="${pageInfo.hasPreviousPage }">
                        <li><a href="${APP_PATH }/employees?pageNum=${pageInfo.pageNum-1 }"
                            aria-label="Previous"> <span aria-hidden="true">&laquo;</span></a></li>
                      </c:if>
                      <c:forEach items="${pageInfo.navigatepageNums }" var="navigatePageNum">
                        <c:if test="${navigatePageNum == pageInfo.pageNum }">
                          <li class="active"><a href="#">${navigatePageNum } <span
                                class="sr-only">(current)</span></a></li>
                        </c:if>
                        <c:if test="${navigatePageNum != pageInfo.pageNum }">
                          <li><a href="${APP_PATH }/employees?pageNum=${navigatePageNum }">${navigatePageNum }</a></li>
                        </c:if>
                      </c:forEach>
                      <c:if test="${pageInfo.hasNextPage }">
                        <li><a href="${APP_PATH }/employees?pageNum=${pageInfo.pageNum+1 }"
                            aria-label="Next"> <span aria-hidden="true">&raquo;</span></a></li>
                      </c:if>
                        <li><a href="${APP_PATH }/employees?pageNum=${pageInfo.pages }">末頁</a></li>
                  </ul>
                </nav>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
</body>
</html>
           

總結:

1. 使用 c:forEach 标簽周遊 pageInfo 中的結果集 list ,填充結果行。

2. list 的長度最大為 pageSize。

3. 分頁資訊是直接從 pageInfo 中得到的。

4. 分頁導航欄的繪制以及對應的請求連結,都是和 pageInfo 中的分頁資訊相關。

5. PageHelper 插件很好用,設定分頁和取值都非常友善、直覺。

6. 個人對前端技術的不足,表現在分頁導航按鈕對齊等美觀問題上,在 department.jsp 中已經解決。

7. 這種方式是在傳回的 Model 中封裝了 PageInfo 對象,對于移動端可能還是存在問題的。