1. 程式人生 > >從零開始寫javaweb框架筆記9-細節完善與程式碼優化-完善控制器層

從零開始寫javaweb框架筆記9-細節完善與程式碼優化-完善控制器層

    在這一小節中,我們開始寫jsp頁面

 開啟/WEB-INF/view/customer.jsp檔案,完成如下程式碼:

<%--
  Created by IntelliJ IDEA.
  User: jack
  Date: 2015/12/5
  Time: 23:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="BASE" value="${pageContext.request.contextPath}"/>
<html>
<head>
    <title>客戶管理</title>
</head>
<body>
<h1>客戶列表</h1>
<table>
  <thead>
  <tr>
    <th>客戶名稱</th>
    <th>聯絡人</th>
    <th>電話號碼</th>
    <th>郵箱地址</th>
    <th>操作</th>
  </tr>
  </thead>
  <tbody>
  <c:forEach var="customer" items="${customerList}">
    <tr>
      <td>${customer.name}</td>
      <td>${customer.contact}</td>
      <td>${customer.telephone}</td>
      <td>${customer.email}</td>
      <td>
        <a href="${BASE}/customer_edit?id=${customer.id}">編輯</a>
        <a href="${BASE}/customer_delete?id=${customer.id}">刪除</a>
      </td>
    </tr>
  </c:forEach>
  </tbody>
</table>
</body>
</html>

   小技巧:在IDEA中,查詢檔案三種方法,ctrl+n,根據java類名進行查詢,ctrl+shift+n,根據任意檔名進行查詢,在project目錄樹中,使用ctrl+shift+f在指定路徑下查詢檔案

     我們已經完成了第一個jsp頁面的編寫了,現在我們部署到Tomcat中,具體的部署方法,參考http://blog.csdn.net/j903829182/article/details/50097471,然後再IDEA中啟動tomcat,我在啟動tomcat的時候,爆錯了,錯誤關鍵資訊如下:

Caused by: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed 


to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/chapter2]]


Caused by: java.lang.IllegalArgumentException: Invalid <url-pattern> customer_create in servlet mapping

然後,我通過網上找資料,看到資料上說是web.xml裡面的路徑配置有問題,但是我這裡使用的是servlet3,沒有在web.xml裡面配置啊,  但是我使用了annotation來進行配置,當看到Invalid <url-pattern> customer_create in servlet mapping這個資訊的時候,我就想是不是以前customer_create裡面的註解配置,錯誤了,然後仔細檢查的確配置錯誤了,

正確的應該是:

@WebServlet("/customer_create")
我配置錯誤的為:
@WebServlet("customer_create")
   所以解決辦法很簡單了,改為正確的配置就ok了。

      解決錯誤後,開啟瀏覽器,輸入地址http://localhost:8080/chapter2/customer然後,我們就會看到下面的介面,如下圖:


     現在CutomerServlet已經開發完畢了,但是還有四個Servlet等待著我們去完成。

     我們可以想象,隨著業務需求的不斷擴充套件,請求個數一定會不段增長,那麼Servlet的數量一定會不斷增多,勢必會增加我們日後維護的工作量,因此我們應該想一個辦法減少Servlet的數量。

     是否將同一個業務模組的Servlet合併到一個類中去呢?比如我們正在開發的這五個Servlet:CustomerServlet,CustomerShowServlet,CustomerCreateServlet,CustomerEditServlet,CustomerDeleteServlet,合併到一個名為CustomerController類中。

    也就是說,在CustomerController中包含了若干方法,每個方法都處理一種特定的請求,就像下面這樣:

package org.jack.com.controller;

/**
 * Created by jack on 2016/1/10.
 */

import org.jack.com.model.Customer;
import org.jack.com.service.CustomerService;
import java.util.List;
import java.util.Map;

/**
 * 處理客戶管理相關請求
 */
@Controller
public class CustomerController {
    @Inject
    private CustomerService customerService;
    /**
     * 進入客戶列表介面
     */
    @Action("get:/customer")
    public view index(Param param){
        List<Customer> customerList=customerService.getCustomerList();
        return new view("customer_show.jsp").addModel("customerList",customerList);
    }
    /**
     * 顯示客戶資訊
     */
    @Action("get:/customer_show")
    public view show(Param param){
        long id=param.getLong("id");
        Customer customer=customerService.getCustomer(id);
        return new view("customer_show.jsp").addModel("customer",customer);
    }
    /**
     * 進入建立客戶 介面
     */
    @Action("get:/customer_create")
    public view create(Param param){
        return new view("customer_create.jsp");
    }
    /**
     * 處理建立客戶請求
     */
    @Action("post:/customer_create")
    public Data createSubmit(Param param){
        Map<String,Object> fieldMap=param.getMap();
        boolean result=customerService.createCustomer(fieldMap);
        return new Data(result);
    }
    /**
     * 進入編輯客戶介面
     */
    @Action("get:/customer_edit")
    public view edit(Param param){
        long id=param.getLong("id");
        Customer customer=customerService.getCustomer(id);
        return new View("customer_edit.jsp").addModel("customer",customer);
    }
    /**
     * 處理編輯客戶請求
     */
    @Action("put:/customer_edit")
    public Data editSubmit(Param param){
        long id=param.getLong("id");
        Map<String,Object> fieldMap=param.getMap();
        boolean result=customerService.updateCustomer(id,fieldMap);
        return new Data(result);
    }
    /**
     * 處理編輯客戶請求
     */
    @Action("delete:/customer_edit")
    public view delete(Param param){
        long id=param.getLong("id");
        boolean result=customerService.deleteCustomer(id);
        return new Data(result);
    }
}

  1)在控制器類上,使用Controller註解,標明該類是一個控制器。

  2)在成員變數上,使用Inject註解,自動建立該成員變數的例項,有一種流行的名稱叫注入

  3)在控制器類中包含若干方法(稱為Action),每個方法都會只用Get/Post/Put/Delete註解,用於指定請求型別與請求路徑。

   4)在Action的引數中,通過Param物件封裝所有請求引數,可根據getLong/getFieldMap等方法獲取具體型別或所有的請求引數。

  5)在Action的返回值,使用View封裝一個jsp頁面,使用Data封裝一個JSON資料。

   有了這個CustomerController以後,Servlet數量一下子就降下來了,而且還遮蔽了技術細節,這種方式將MVC架構變得更加輕量級。那怎麼開發這樣一個輕量級的框架呢?在後面我們我們來慢慢學習。

     總結:在前面,我們針對業務需求進行了簡單的分析,找出了核心的功能點,並設計了相關的用例額,根據業務實體確定了表結構,通過介面原型設計了URL規範這些設計工作可以用來以後的開發中來。在開發階段,我們藉助了MVC架構,將開發過程分解。我們對服務層進行了細化,使用Apache Commons DbUtils類庫開發了一個輕量級JDBC框架。此外還是用了JUnit對每個服務方法進行了單元測試,並提供了一種資料庫初始化的解決方案,讓單元測試更加具備可測性。針對一個具體業務需求,從後端到前端一次整合,使資料得到了實現,但介面有些醜陋,在以後的我會慢慢的完善,使用bootstrap來美化介面。