1. 程式人生 > >JavaEE-jsp、el、jstl和顯示使用者綜合案例

JavaEE-jsp、el、jstl和顯示使用者綜合案例

1. jsp基礎

1.1 jsp概念

  • JSP(java server Pages),java的伺服器頁面,裡面包含html和java程式碼。其中html負責靜態內容,Java程式碼負責動態內容。
  • 特點:
    • 跨平臺
    • 業務程式碼相分離
    • 元件重組
    • 預編譯
  • jsp解決的問題:
    • 簡化html書寫,動態生成頁面

1.2 jsp的執行原理

圖解:

1536805943433

  • jsp的底層是一個Servlet。
  • jsp在伺服器中先翻譯成一個java檔案(一個類),該類繼承HttpJspBase,而HttpJspBase又是繼承httpServlet。故jsp程式碼中可以直接呼叫Servlet的request和response物件。
  • 編寫在jsp的程式碼在翻譯時會封裝到該Servlet的service方法中。
  • 伺服器會完成jsp的翻譯,編譯成.class檔案,以及載入的操作,最後將操作之後的html頁面傳送給瀏覽器

1.3 jsp的基本語法

1.3.1 jsp註釋

  • 格式:<%-- jsp註釋 --%>
  • 特點:
    • jsp的註釋能註釋靜態內容和java程式碼,且不會顯示在原始碼上,更加安全;

    • html註釋通過檢視網頁原始碼仍可看到;

      html註釋只能註釋靜態內容(html、css、js),而裡面如0有java程式碼仍能執行

    • 推薦使用jsp的註釋。

1.3.2 jsp編寫java程式碼方式

1.3.2.1 指令碼片段格式
  • 格式:<% Java程式碼片段 %>
  • 特點和作用:在指令碼片段中書寫的Java程式碼,會翻譯到java檔案中的_jspService方法中
  • 注意事項:指令碼片段可以分開書寫,但最後會組合在一起
1.3.2.2 指令碼宣告
  • 格式:<%! 全域性成員 %>

  • 特點和作用:在指令碼宣告中書寫的Java程式碼,會翻譯在類的成員位置上,用來宣告成員變數或具有返回值的成員方法

  • 注意事項:宣告方法的時候,不要宣告與jsp翻譯的java檔案中預設的一些方法或者變數同名的方法或者變數

1.3.2.3 指令碼表示式
  • 格式:<%= 輸出頁面的內容 %>

  • 特點:指令碼表示式書寫的java程式碼,會翻譯到java檔案中的_jspService方法內,被out.print()輸出到頁面

    這裡的out物件是一個字元輸出流

  • 作用:代替response向頁面輸出內容

  • 注意事項:

    • 指令碼表示式和response不能同時使用,否則會出現頁面輸出順序和程式碼順序錯亂的情況;
    • 指令碼表示式不能包含分號
1.3.2.4 jsp編寫java示例程式碼:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp基本語法</title>
</head>
<body>
<h4>1.指令碼片段</h4>
<%
    //在jsp內可以編寫java程式碼
    //使用集合儲存列表
    List<String> userList = new ArrayList<>();
    userList.add("明明");
    userList.add("大黃");
    userList.add("狗蛋");
    userList.add("jojo");
%>
<table width="50%" border="1px" style="border-collapse: collapse;text-align:center" align="center">
    <tr>
        <th>序號</th>
        <th>姓名</th>
    </tr>
    <%--如果按照原來的做法,在html需要一個個的新增td。而使用jsp可以直接插入Java程式碼--%>
    <%for (int i = 0; i < userList.size(); i++) {%>
    <tr>
        <td><%out.write(i + 1);%></td>
        <td><%out.write(userList.get(i));%></td>
    </tr>
    <%}%>
</table>

<h4>2.指令碼表示式</h4>
<%--指令碼表示式可以將out.write()或者out.print()進行簡化--%>
<table width="50%" border="1px" style="border-collapse: collapse;text-align:center" align="center">
    <tr>
        <th>序號</th>
        <th>姓名</th>
    </tr>
    <%for (int i = 0; i < userList.size(); i++) {%>
    <tr>
        <td><%=i + 1%>
        </td>
        <td><%=userList.get(i)%>
        </td>
    </tr>
    <%}%>
</table>

<h4>3.指令碼宣告</h4>
<%--在成員位置宣告變數或者方法--%>
<%!
    /*定義方法*/
    public int sum(int i, int j) {
        return i + j;
    }
%>
<%--呼叫方法--%>
<p>1+2的和:<%=sum(1, 2)%></p>

</body>
</html>

1.4 jsp和Servlet技術的選用

  • servlet:主要負責產生動態資源資料。接收瀏覽器請求,從資料庫中獲取資料,並存儲在域物件中,然後跳轉到jsp頁面
  • jsp:主要負責顯示佈局動態資源資料。獲取域物件的資料,並使用html佈局動態頁面響應瀏覽器。
圖解

1536929667661

1.5 簡化jsp

  • 頁面上的指令碼表示式<%=java程式碼%>☞使用EL技術代替
  • 頁面上的指令碼程式碼片段<%java程式碼;%>的迴圈、條件判斷等☞使用JSTL技術代替

2. EL表示式

EL(Expression Language):代替jsp中指令碼表示式的功能,簡化對java程式碼的操作。

2.1 EL表示式的格式和作用

  • 格式:${域裡面的key或者表示式}
  • 作用:從域物件中查詢指定的資料
  • 前提:資料都必須存入域物件el才能獲取到!!

2.2 EL表示式的使用

2.2.1 EL獲得容器(域物件)的資料

  • el通過域物件中的name,來獲取對應的value。如果name不一樣,可以直接用name來獲取value;
  • 預設情況下,el會依次從request==>session==>servletContext的順序獲取name對應value,一旦獲取成功將不會繼續往下獲取。如果多個域物件的name一樣,只會按照順序獲取第一個;
  • el如果沒有獲取到name對應的value,則不會顯示,而不是返回null;
  • 如果要獲取指定的域物件資料,使用下表的el物件.域物件name獲取(重要)。如果不指定則按預設處理。
域物件 對應的el物件
request requestScope
session sessionScope
servletContext applicationScope
<h3>使用el獲取域物件資料</h3>
<%
    //往各個域裡面儲存資料
    request.setAttribute("requestName","requestAdmin");
    session.setAttribute("sessionName","sessionAdmin");
request.getServletContext().setAttribute("servletContextName","servletContextAdmin");
%>
<%--使用el表示式獲取域裡面的資料--%>
<p>從request裡面獲取資料:${requestName}</p>
<p>從session裡面獲取資料:${sessionName}</p>
<p>從servletContext裡面獲取資料:${servletContextName}</p>

<%
    //往各個域裡面儲存資料
    request.setAttribute("name","requestAdmin");
    session.setAttribute("name","sessio nAdmin");
    request.getServletContext().setAttribute("name","servletContextAdmin");
%>
<p>從域裡面獲取資料:${name}</p><%--輸出requestAdmin,el獲取域裡面的資料會依次從request/session/servletContext獲取資料,查詢到為止--%>

<p>從session域裡面name資料:${sessionScope.name}</p>
<p>從servletContext域裡面name資料:${applicationScope.name}</p>
<p>從request域裡面name資料:${requestScope.name}</p>

2.2.2 EL獲取和解析複雜資料

2.2.2.1 獲取陣列的元素
  • 獲取陣列:${陣列名}

  • 格式:${陣列名[index]},其中index為元素的索引

  • 如果元素是一個實體類物件,如果要獲取物件的變數,格式為:${陣列名[index].變數名}

2.2.2.2 獲取集合的元素
  • 獲取集合:${List集合名}${Map集合名}

  • List集合獲取元素與陣列相同,${List集合名[index]}

  • Map集合根據key獲取value:${Map集合名[key]}或者${Map集合名.key}

  • 注意事項:設定map集合資料的key,儘量不要出現”.“,如果出現,只能用[]獲取

2.2.2.3 獲取JavaBean資料
  • 如果要獲取JavaBean物件的屬性值,可以直接用屬性名調取,el自動呼叫對應的getXxx方法
  • 格式:${JavaBean物件.屬性名}${JavaBean物件[屬性名]}
2.2.2.4 el獲取資料的示例程式碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el獲取複雜資料</title>
</head>
<body>

<h4>1.使用el獲得陣列的資料</h4>
<%
    /*新增資料到陣列中*/
    User[] users = new User[2];
    users[0] = new User("狗蛋",18);
    users[1] = new User("明明",20);
    //記得el必須要將資料新增到域物件中
    request.setAttribute("users",users );
%>
<p>獲取數組裡面第一個元素的name屬性值:${users[0].name}</p>
<p>獲取數組裡面第一個元素的age屬性值: ${users[0].age}</p>
<p>獲取數組裡面第二個元素的name屬性值:${users[1].name}</p>
<p>獲取數組裡面第二個元素的age屬性值:${users[1].age}</p>

<h4>2.使用el獲得list集合的資料</h4>
<%
    /*新增資料到陣列中*/
    List<User> list = new ArrayList<>();
    list.add(new User("王全",20));
    list.add(new User("dio",98));
    //記得el必須要將資料新增到域物件中
    request.setAttribute("list",list );
%>
<p>獲取List裡面第一個元素的name屬性值:${list[0].name}</p>
<p>獲取List裡面第一個元素的age屬性值: ${list[0].age}</p>
<p>獲取List裡面第二個元素的name屬性值:${list[1].name}</p>
<p>獲取List裡面第二個元素的age屬性值:${list[1].age}</p>

<h4>3.使用el獲得map集合的資料</h4>
<%
    /*新增資料到陣列中*/
    Map<String,User> map = new HashMap<>();
    map.put("zs",new User("張三",20));
    map.put("ls",new User("李四",30));
    //記得el必須要將資料新增到域物件中
    request.setAttribute("map",map );
%>
<p>獲取Map裡面第一個元素的name屬性值:${map.zs.name}</p>
<p>獲取Map裡面第一個元素的age屬性值: ${map.zs.age}</p>
<p>獲取Map裡面第二個元素的name屬性值:${map[lisi].name}</p>
<p>獲取Map裡面第二個元素的age屬性值:${map[lisi].age}</p>

<h4>4.使用el獲得JavaBean的資料</h4>
<%
    //往域裡面寫javaBean
    request.setAttribute("user",new User("JoJO",18));
    //el獲取javaBean資料時,".屬性名"就會自動呼叫屬性的get封裝方法。
%>
<p>獲取user物件裡面name屬性值:${user.name}</p>
<p>獲取user物件裡面age屬性值:${user.age}</p>


</body>
</html>

2.2.3 EL執行運算

2.2.3.1 算術運算子
  • 在el表示式中可使用算術運算子
注意事項
  1. 在EL中,只要是數字就能執行運算,EL在執行計算的時候,會將數字除盡,最多保留16位小數(而java中整數相除取整數);
  2. 在EL中,如果在一個算式中有資料不存在,那麼這個資料不參與運算,不報錯繼續執行
  3. 在EL中,算術運算子只能做數學運算,不具備java程式碼中的拼字串的功能,即3+"5"的結果是8而不是35。
  4. 使用時都必須先將判斷的條件提交到域物件中!
2.2.3.2 邏輯運算子

1536813232709

注意事項
  • el運算子不支援異或^運算
2.2.3.3 比較運算

1536813412813

注意事項
  • 使用比較運算子要保證資料是存在的並且是可比較
2.2.3.4 Empty運算子和三目運算子
  • Empty運算子:${empty 域裡面的資料}

    常用的Empty運算 執行結果
    ${empty ""} 如果資料為空字串,則返回true
    ${empty null} 如果資料為null,返回true
    ${empty list} 如果list元素個數為0,返回true
    ${empty str} 如果字串為空,返回true

    Empty運算子對應的取反方法

    ${not empty 域裡面的資料}

  • 三目運算子,用法與Java一致:${三目運算子}

3. JSTL的核心標籤庫使用

3.1 JSTL概述

  • JSTL(jsp的標準標籤庫:Jsp Standard Tag Library)。儲存許多伺服器端標籤(封裝了具有特定的功能的java程式碼,以標籤形式編寫,代替特定功能的java程式碼)。

3.2 jstl標籤的安裝

3.2.1 導包

  • javax.servlet.jsp.jstl.jar

  • jstl-impl.jar

3.2.2 使用taglib指令在jsp頁面匯入要使用的jstl標籤庫

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

其中:taglib是匯入標籤庫,uri選擇核心標籤庫core,prefix用於指定將要使用的標籤起字首名,一般是標籤庫的第一個字母

3.3 常用的jstl標籤

3.3.1 if標籤

  • 起判斷的作用,相當於java程式碼的if(){}
3.3.1.1 if標籤屬性介紹
屬性名 是否支援el 屬性型別 屬性描述
test boolean 編寫el條件表示式(表示式結果為true執行,為false不執行)
var × String 設定儲存test屬性的結果儲存的域物件的名稱
scope × String 指定儲存test屬性的結果的域物件。

3.3.2 choose標籤

  • <c:choose>標籤用於指定多個條件選擇的組合邊界,它必須與<c:when><c:otherwise>標籤一起使用。三個標籤組合發揮java程式碼if(){}else if(){} else{}語句的作用

  • 其中: <c:otherwise>,相當於else{}。 <c:when>,相當於if(){}else if(){}<c:when>標籤含有test屬性,作用與if相同

  • 注意事項:三個標籤必須組合使用,一組標籤中不能出現兩個<c:otherwise>

3.3.3 foreach標籤

  • 相當於Java的for迴圈
屬性名 是否支援el 屬性型別 屬性描述
var × String 在不迴圈物件的時候,儲存的是控制迴圈的變數;在迴圈物件的時候,儲存的是被迴圈物件中的元素
items 任何型別 指定要迴圈的物件
varStatus × String 儲存迴圈過程變數資訊(迴圈索引、迴圈序號)
begin int 迴圈開始變數值
end int 迴圈結束變數值
step int 迴圈變數遞增值,沒有設定預設是1
注意事項
  • varStatus,儲存迴圈過程變數資訊。在forEach迴圈過程中產生很多迴圈資訊,比如迴圈索引,迴圈序號。
  • forEach標籤會將這些資訊儲存到varStatus物件裡面:
    index,迴圈索引,從0開始
    count,迴圈序號,從1開始
3.3.3.1 有限次數的迴圈
  • 格式:

    <c:forEach begin="開始變數值" end="結束變數值" step="變數遞增值">
        <%--迴圈體程式碼--%>
    </c:forEach>
    
3.3.3.2 迴圈物件(陣列、list、map)
  • 格式:

    <c:forEach items="使用el獲取域裡儲存的集合資料" var="接收迴圈遍歷每個元素物件">
        <%--迴圈程式碼--%>
    </c:forEach>
    

3.4 jstl標籤示例程式碼

<%@ page import="model.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>if、choose、foreach</title>
</head>
<body>
<h4>1.if標籤</h4>
<c:if test="${true}" scope="session" var="flag">
    if標籤示例1
</c:if>
<br/>測試if標籤,獲取test屬性的值,從知道的session容器中獲取:${sessionScope.flag}
<%
    session.setAttribute("user","admin" );
%>
<c:if test="${not empty user}">
    <p>您好,歡迎${user}登入</p>
</c:if>
<c:if test="${empty user}">
    <p>您還沒登入呢</p>
</c:if>

<h4>2.choose標籤</h4>
<c:choose>
    <c:when test="${not empty user}">
        <p>您好,歡迎${user}登入</p>
    </c:when>
    <c:otherwise>
        <p>您還沒登入呢</p>
    </c:otherwise>
</c:choose>

<h4>3.foreach標籤</h4>
<h5>5.1 有限迴圈次數</h5>
<c:forEach begin="1" end="5" step="1">
    <%--迴圈列印5次--%>
    <%="你好,java"%>
<br/>
</c:forEach>

<h5>5.2 遍歷集合</h5>
<%
    List<User> userList = new ArrayList<User>();
    userList.add(new User("王全",20));
    userList.add(new User("dio",98));
    userList.add(new User("JoJo",18));
    //一定要往域裡面放域物件
    request.setAttribute("userList", userList);
%>
<table width="50%" border="1px" style="border-collapse: collapse;text-align:center" align="center">
    <tr>
        <th>序號</th>
        <th>人員姓名</th>
        <th>人員年齡</th>
    </tr>
    <c:forEach items="${userList}" var="user" varStatus="i">
        <tr>
            <td>${i.count}</td>
            <td>${user.name}</td>
            <td>${user.age}</td>
        </tr>
    </c:forEach>
</table>
</html>

4. 三層架構和MVC模式

圖解

1536841440537

其中javabean就只用於負責封裝資料

5. MVC+三層架構完成聯絡人列表案例

5.1 準備工作

  1. 匯入包,包括druid、JdbcTemplate、資料庫驅動包、beanutils包。放到web/WEB-INF/lib目錄下

  2. 準備好druid配置檔案

  3. 準備好bootstrap資源,放在web目錄下

  4. 構建架構

    1537154771074

  5. 建立實體類

    public class Contact {
        private int id;
        private String name;
        private String sex;
        private int age;
        private String address;
        private String qq;
        private String email;
    
        public Contact() {
        }
    
        public Contact(int id, String name, String sex, int age, String address, String qq, String email) {
            this.id = id;
            this.name = name;
            this.sex = sex;
            this.age = age;
            this.address = address;
            this.qq = qq;
            this.email = email;
        }
        /*此處省略toString()和getter&setter,實際是有的*/
    }
    
  6. 放入JDBCUtils工具類

5.2 三層架構

5.2.1 dao層

/*
底層如果出現異常,要手動拋給上一層。通過web層展示出異常的情況,從而找對應的人維護。
下面用資料庫最大的異常SQLException
 */
public class ContactDao {
    private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());


    public List<Contact> getAllContacts() {
        String sql = "select * from contact;";
        return jdbcTemplate.query(sql,new BeanPropertyRowMapper<Contact>(Contact.class));
    }


    public int addContactToDao(Contact contact) {
        String sql = "insert into contact values(null,?,?,?,?,?,?);";
        return jdbcTemplate.update(sql, contact.getName(), contact.getSex(),
                contact.getAge(), contact.getAddress(), contact.getQq(), contact.getEmail());
    }

    public int deleteContactFromDao(String id) {
        String sql = "delete from contact where id = ?;";
        return jdbcTemplate.update(sql, id);
    }

    public int updateContactToDao(Contact updateContact) {
        System.out.println("dao:" + updateContact);
        String sql = "update contact set sex = ?,age = ?,address = ?,qq = ?,email = ? where id = ?;";
        return jdbcTemplate.update(sql,updateContact.getSex(),updateContact.getAge(),updateContact.getAddress(),
                updateContact.getQq(),updateContact.getEmail(),updateContact.getId());
    }

    public Contact findById(int id) {
        String sql = "select * from contact where id = ?;";
        return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Contact.class),id);
    }
}

5.2.2 service層

/*
業務層編寫要求:
將異常手動拋到web層,由web層根據不同的異常做出不同的提示
(一方面給使用者友好的提示,一方面給後臺人員提醒是哪部分出問題,從而安排對應的程式設計師維護)

下面程式碼是手動拋最大的異常,實際工程可以細分

此外,deleteContact()、updateContact()可以不用返回值
 */
public class ContactService {
    private ContactDao contactDao = new ContactDao();

    public List<Contact> getContacts(){
        return contactDao.getAllContacts();
    }

    public boolean addContact(Contact contact) throws Exception{
        //如果聯絡人姓名為空,那麼視為新增失敗
        if (contact.getName() != null) {
            int rows = contactDao.addContactToDao(contact);
            return rows > 0;
        } else {
            return false;
        }
    }

    public boolean deleteContact(String id) throws Exception{
        //根據id刪除聯絡人
       return contactDao.deleteContactFromDao(id) > 0;

    }

    public boolean updateContact(Contact updateContact) throws Exception{
        //呼叫dao修改聯絡人
        return contactDao.updateContactToDao(updateContact) > 0;
    }

    public Contact queryById(int id) throws Exception{
        return contactDao.findById(id);
    }
}

5.2.3 web層和使用者頁面

5.2.3.1 展示所有聯絡人
瀏覽器端:list.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--匯入jstl包--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!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>Bootstrap模板</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>
    <style type="text/css">
        td, th {
            text-align: center;
        }
    </style>
</head>
<body>
<div class="container">
    <h3 style="text-align: center">顯示所有聯絡人</h3>
    <table border="1" class="table table-bordered table-hover">
        <tr class="success">
            <th>編號</th>
            <th>姓名</th>
            <th>性別</th>
            <th>年齡</th>
            <th>籍貫</th>
            <th>QQ</th>
            <th>郵箱</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${contactList}" var="contact">
        <tr>
            <td>${contact.id}</td>
            <td>${contact.name}</td>
            <td>${contact.sex}</td>
            <td>${contact.age}</td>
            <td>${contact.address}</td>
            <td>${contact.qq}</td>
            <td>${contact.email}</td>
            <td><a class="btn btn-default btn-sm" href="/QueryByIDServlet?id=${contact.id}">修改</a>&nbsp;<a class="btn btn-default btn-sm" href="/DeleteContactServlet?id=${contact.id}">刪除</a></td>
        </tr>
        </c:forEach>
        <tr>
            <td colspan="8" align="center"><a class="btn btn-primary" href="add.jsp">新增聯絡人</a></td>
        </tr>
    </table>
</div>
</body>
</html>
伺服器端:
@WebServlet(urlPatterns = "/ContactServlet")
public class ContactServlet extends HttpServlet {

    private ContactService service = new ContactService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲得資料庫的資料
        List<Contact> contactList = service.getContacts();
        //封裝到request域中
        request.setAttribute("contactList", contactList);
        //請求轉發到jsp中
        request.getRequestDispatcher("list.jsp").forward(request,response );

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //*如果post方式的執行內容與get不同,則刪掉下面程式碼重寫即可
        doGet(request, response);
    }
}
5.2.3.2 新增聯絡人: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="/AddContactServlet" 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="sex" value="男" checked="checked"/>男
            <input type="radio" name="sex" 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="address">籍貫:</label>
            <select name="address" class="form-control" id="jiguan">
                <option value="廣東">廣東</option>
                <option value="廣西">廣西</option>
                <option value="湖南">湖南</option>
            </select>
        </div>

        <div class="form-group">
            <label for="qq">QQ:</label>
            <input type="text" class="form-control" name="qq" placeholder="請輸入QQ號碼"/>
        </div>

        <div class="form-group">
            <label for="email">Email:</label>
            <input type="text" class="form-control" name="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="返回" onclick="goback()" />
        </div>
    </form>
</div>
<script>
    function goback() {
        history.back();
    }
</script>
</body>
</html>

伺服器端:

@WebServlet(urlPatterns = "/AddContactServlet")
public class AddContactServlet extends HttpServlet {

    private ContactService service = new ContactService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解決響應亂碼問題
        response.setContentType("text/html;charset=utf-8");
        //解決請求亂碼問題
        request.setCharacterEncoding("utf-8");
        try {
            Map<String, String[]> ContactMap = request.getParameterMap();
            Contact contact = new Contact();
            BeanUtils.populate(contact,ContactMap);
            //使用service的新增聯絡人方法
            boolean flag = service.addContact(contact);
            if (!flag){
                response.getWriter().write("alert('您還沒有新增聯絡人姓名!請重新新增');");
            } else {
                //新增成功請求轉發到ContactServlet
                //request.getRequestDispatcher("/ContactServlet").forward(request,response);
                //也可以用重定向。因為用請求轉發的話新增完的路徑仍為add,會為使用者造成困擾,這裡就建議用重定向
                response.sendRedirect("/ContactServlet");
            }
        } catch (Exception e) {
            //操作檯列印異常給維護人員看
            e.printStackTrace();
            //給使用者友好提示
            response.getWriter().write("業務繁忙,請稍後再試");
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //*如果post方式的執行內容與get不同,則刪掉下面程式碼重寫即可
        doGet(request, response);
    }
}
5.2.3.3 刪除聯絡人
伺服器端:
@WebServlet(urlPatterns = "/DeleteContactServlet")
public class DeleteContactServlet extends HttpServlet {
    /*
    思路:刪除聯絡人前必須知道是哪個聯絡人,可以通過主鍵找出需要刪除的聯絡人資料,所以在list.jsp中需要將主鍵傳過來。
         可以通過在請求引數中新增?id=${contact.id}來傳遞,這是利用了get提交方式傳送請求引數
     */
    private ContactService service = new ContactService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //獲取請求引數id
        String id = request.getParameter("id");
        //根據id刪除聯絡人
        try {
            service.deleteContact(id);
        } catch (Exception e) {
            //操作檯列印異常給維護人員看
            e.printStackTrace();
            //給使用者友好提示
            response.getWriter().write("業務繁忙,請稍後再試");
        }
        //刪除完後直接跳轉到ContactServlet
        response.sendRedirect("/ContactServlet");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //*如果post方式的執行內容與get不同,則刪掉下面程式碼重寫即可
        doGet(request, response);
    }
5.2.3.4 修改聯絡人