(9)jsp技術的使用

1,什麼是 jsp ,它有什麼用?

2,jsp 的本質是什麼?

3,jsp 的三種語法

4,jsp 九大內置對象

5,jsp 四大域對象

6,jsp 中的 out 輸出和 response.getWriter 輸出的區別

7,jsp 的常用標籤

8,jsp 的練習題

9,Listener 監聽器

什麼是 jsp ,它有什麼用?

  • jsp 的全稱是 java server pages。Java 的服務器頁面。

  • jsp 的主要作用是代替 Servlet 程序回傳 html 頁面的數據。

  • 因爲 Servlet 程序回傳 html 頁面數據是一件非常繁鎖的事情。開發成本和維護成本都極高。

  • Servlet 回傳 html 頁面數據的代碼:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 通過響應的回傳流回傳 html 頁面數據
    resp.setContentType("text/html; charset=UTF-8");
    PrintWriter writer = resp.getWriter();
    writer.write("<!DOCTYPE html>\r\n");
    writer.write(" <html lang=\"en\">\r\n");
    writer.write(" <head>\r\n");
    writer.write(" <meta charset=\"UTF-8\">\r\n");
    writer.write(" <title>Title</title>\r\n");
    writer.write(" </head>\r\n");
    writer.write(" <body>\r\n");
    writer.write(" 這是 html 據 頁面數據 \r\n");
    writer.write(" </body>\r\n");
    writer.write("</html>\r\n");
    writer.write("\r\n");
}
  • jsp 回傳一個簡單 html 頁面的代碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
這是 html 頁面數據
</body>
</html>
  • jsp 如何訪問:

    jsp 頁面和 html 頁面一樣,都是存放在 web 目錄下。訪問也跟訪問 html 頁面一樣。

    比如:在 web 目錄下有如下的文件:

    web 目錄

    a.html 頁面 訪問地址是 ====》 http://ip:port/工程路徑/a.html
    b.jsp 頁面 訪問地址是 ====》http://ip:port/工程路徑/b.jsp

jsp 的本質是什麼?

  • jsp 頁面本質上是一個 Servlet 程序。

  • 當我們第一次訪問 jsp 頁面的時候。Tomcat 服務器會幫我們把 jsp 頁面翻譯成爲一個 java 源文件。並且對它進行編譯成爲.class 字節碼程序。我們打開 java 源文件不難發現其裏面的內容是:
    在這裏插入圖片描述

  • HttpJspBase 類。它直接地繼承了 HttpServlet 類。也就是說。jsp 翻譯出來的 java 類,它間接了繼承了 HttpServlet 類。也就是說,翻譯出來的是一個 Servlet 程序

  • 總結:通過翻譯的 java 源代碼我們就可以得到結果:jsp 就是 Servlet 程序。

jsp 的三種語法

1,jsp 頭部的 page 指令

  • jsp 的 page 指令可以修改 jsp 頁面中一些重要的屬性,或者行爲。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
屬性 含義
language 表示 jsp 翻譯後是什麼語言文件,暫時只支持 java
contentType 表示 jsp 返回的數據類型是什麼,也是源碼中 response.setContentType()參數值
pageEncoding 表示當前 jsp 頁面文件本身的字符集
import 跟 java 源代碼中一樣。用於導包,導類
autoFlush 設置當 out 輸出流緩衝區滿了之後,是否自動刷新衝級區。默認值是 true
pageEncoding 表示當前 jsp 頁面文件本身的字符集
errorPage 設置當 jsp 頁面運行時出錯,自動跳轉去的錯誤頁面路徑
isErrorPage 設置當前 jsp 頁面是否是錯誤信息頁面。默認是 false。如果是 true 可以獲取異常信息
session 設置訪問當前 jsp 頁面,是否會創建 HttpSession 對象。默認是 true
extends 設置 jsp 翻譯出來的 java 類默認繼承誰
  • 緩衝區溢出錯誤:
    在這裏插入圖片描述

2,jsp 中的常用腳本

  • 聲明腳本( 極少使用)

    聲明腳本的格式是: <%! 聲明 java 代碼 %>

    作用:可以給 jsp 翻譯出來的 java 類定義屬性和方法甚至是靜態代碼塊。內部類等。

    • 案例:
	<%--1 、聲明類屬性 --%>
	<%!
  		private Integer id;
  		private String name;
  		private static Map<String,Object> map;
	%>
	
	<%--2 、聲明 static 靜態代碼塊 --%>
	<%!
  		static {
    		map = new HashMap<String,Object>();
    		map.put("key1", "value1");
    		map.put("key2", "value2");
    		map.put("key3", "value3");
  		}
	%>
	
	<%--3 、聲明類方法 --%>
	<%!
  		public int abc(){
    		return 12;
  		}
	%>
	
	<%--4 、聲明內部類 --%>
	<%!
  		public static class A {
    		private Integer id = 12;
    		private String abc = "abc";
  		}
	%>
  • 表達式腳本 (常用)

    表達式腳本的格式是:<%=表達式%>

    表達式腳本的作用是:的 jsp 頁面上輸出數據。

    • 表達式腳本的特點:

      ①、所有的表達式腳本都會被翻譯到_jspService() 方法中

      ②、表達式腳本都會被翻譯成爲 out.print()輸出到頁面上

      ③、由於表達式腳本翻譯的內容都在_jspService() 方法中,所以_jspService()方法中的對象都可以直接使用。

      ④、表達式腳本中的表達式不能以分號結束。

    • 案例:

	<%=12 %> <br>
	<%=12.12 %> <br>
	<%=" 我是字符串" %> <br>
	<%=map%> <br>
	<%=request.getParameter("username")%>
  • 代碼腳本

    • 代碼腳本的格式是:<% java 語句 %>

    • 代碼腳本的作用是:可以在 jsp 頁面中,編寫我們自己需要的功能(寫的是 java 語句)

    • 代碼腳本的特點是:

      ①、代碼腳本翻譯之後都在_jspService 方法中

      ②、代碼腳本由於翻譯到_jspService()方法中,所以在_jspService()方法中的現有對象都可以直接使用。

      ③、還可以由多個代碼腳本塊組合完成一個完整的 java 語句。

      ④、代碼腳本還可以和表達式腳本一起組合使用,在 jsp 頁面上輸出數據

    • 代碼腳本 for 循環語句案例:

  	<body>
  	<table border="1" cellspacing="0">
    	<%
     	 	for (int j = 0; j < 10; j++) {
    	%>
    <tr>
      <td><%=j + 1%></td>
    </tr>
    	<%
      		}
    	%>
  </table>
  </body>

3,jsp 中的三種註釋

  • html 註釋

    html 註釋會被翻譯到 java 源代碼中。在_jspService 方法裏,以 out.writer 輸出到客戶端。

<!-- 這是 html 註釋 -->
  • java 註釋

    java 註釋會被翻譯到 java 源代碼中

<%
// 單行 java 註釋
/* 多行 java 註釋 */
%>
  • jsp 註釋

    jsp 註釋可以注掉,jsp 頁面中所有代碼

<%-- 這是 jsp 註釋 --%>

jsp 九大內置對象

  • jsp 中的內置對象,是指 Tomcat 在翻譯 jsp 頁面成爲 Servlet 源代碼後,內部提供的九大對象,叫內置對象
對象名 含義
request 請求對象
response 響應對象
pageContext jsp的上下文對象
session 會話對象
application ServletContext對象
config ServletConfig對象
out jsp輸出流對象
page 指向當前jsp的對象
exception 異常對象

jsp 四大域對象

域對象名 含義
pageContext (PageContextImpl 類) 當前 jsp 頁面範圍內有效
request (HttpServletRequest 類) 一次請求內有效
session (HttpSession 類) 一個會話範圍內有效(打開瀏覽器訪問服務器,直到關閉瀏覽器)
application (ServletContext 類) 整個 web 工程範圍內都有效(只要 web 工程不停止,數據都在)
  • 域對象是可以像 Map 一樣存取數據的對象。四個域對象功能一樣。不同的是它們對數據的存取範圍,四個域在使用的時候,優先順序分別是,他們從小到大的範圍的順序:

    pageContext ====>>> request ====>>> session ====>>> application

  • 案例:

index.jsp 頁面

  <body>
    <h1>index.jsp 頁面</h1>
    <%
      // 往四個域中都分別保存了數據
      pageContext.setAttribute("key", "pageContext");
      request.setAttribute("key", "request");
      session.setAttribute("key", "session");
      application.setAttribute("key", "application");
    %>
    pageContext 域是否有值:<%=pageContext.getAttribute("key")%> <br>
    request 域是否有值:<%=request.getAttribute("key")%> <br>
    session 域是否有值:<%=session.getAttribute("key")%> <br>
    application 域是否有值:<%=application.getAttribute("key")%> <br>
    <%
      request.getRequestDispatcher("/resp.jsp").forward(request,response);
    %>
  </body>

resp.jsp 頁面

<body>
    <h1>resp.jsp 頁面</h1>
    pageContext 域是否有值:<%=pageContext.getAttribute("key")%> <br>
    request 域是否有值:<%=request.getAttribute("key")%> <br>
    session 域是否有值:<%=session.getAttribute("key")%> <br>
    application 域是否有值:<%=application.getAttribute("key")%> <br>
</body>

jsp 中的 out 輸出和 response.getWriter 輸出的區別

  • response 中表示響應,我們經常用於設置返回給客戶端的內容(輸出)

  • out 也是給用戶做輸出使用的。

  • 當jsp頁面中所有代碼執行完成後會做以下兩個操作:

    ①,執行out.flush()操作,會把out緩衝區中的數據追加寫入到response緩衝區末尾

    ②,會執行response的刷新操作。把全部數據寫給客戶端

  • 由於 jsp 翻譯之後,底層源代碼都是使用 out 來進行輸出,所以一般情況下。我們在 jsp 頁面中統一使用 out 來進行輸出。避免打亂頁面輸出內容的順序。

    out.write() 輸出字符串沒有問題

    out.print() 輸出任意數據都沒有問題(都轉換成爲字符串後調用的 write 輸出)

jsp 的常用標籤

1,jsp 靜態包含

  • <%@ include file=""%> 就是靜態包含file 屬性指定你要包含的 jsp 頁面的路徑地址中第一個斜槓 / 表示爲 http://ip:port/ 工程路徑 / 映射到代碼的 web 目錄

  • 靜態包含的特點:

    ① 、靜態包含不會翻譯被包含的 jsp 頁面。

    ② 、靜態包含其實是把被包含的 jsp 頁面的代碼拷貝到包含的位置執行輸出。

  • 示例

<%@ include file="/include/footer.jsp"%>

2,jsp 動態包含

  • <jsp:include page=""></jsp:include> 這是動態包含,page 屬性是指定你要包含的 jsp 頁面的路徑動態包含也可以像靜態包含一樣。把被包含的內容執行輸出到包含位置

  • 動態包含的特點:

    ①、動態包含會把包含的 jsp 頁面也翻譯成爲 java 代碼

    ②、動態包含底層代碼使用如下代碼去調用被包含的 jsp 頁面執行輸出。JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);

    ③ 、動態包含,還可以傳遞參數

  • 示例說明:

<jsp:include page="/include/footer.jsp">
<jsp:param name="username" value="bbj"/>
<jsp:param name="password" value="root"/>
</jsp:include>
  • 動態包含的底層原理:
    在這裏插入圖片描述

3,jsp 標籤-轉發

  • <jsp:forward page=""></jsp:forward> 是請求轉發標籤,它的功能就是請求轉發page 屬性設置請求轉發的路徑

  • 示例說明:

<jsp:forward page="/scope.jsp"></jsp:forward>

jsp 的練習題

1,jsp 頁面中輸出九九乘法口訣表

    <style type="text/css">
      table{
        width: 650px;
      }
    </style>
  </head>
  <body>
  <h1 align="center">九九乘法口訣表</h1>
  <table align="center">
    <%-- 外層循環遍歷行 --%>
    <% for (int i = 1; i <= 9; i++) { %>
    <tr>
      <%-- 內層循環遍歷單元格 --%>
      <% for (int j = 1; j <= i ; j++) { %>
      <td><%=j + "x" + i + "=" + (i*j)%></td>
      <% } %>
    </tr>
    <% } %>
  </table>
  </body>

2,jsp 輸出一個表格,裏面有 10 個學生信息

  • 思路
    在這裏插入圖片描述
  • Student 類:
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String phone;
}
  • SearchStudentServlet 程序:
/**
 * @author Tommey周
 * @create 2020-05-25 9:24
 */
public class SearchStudentServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 獲取請求的參數,發 sql 語句查詢學生的信息,使用 for 循環生成查詢到的數據做模擬
        List<Student> studentList = new ArrayList<Student>();
        for (int i = 0; i < 10; i++) {
            int t = i + 1;
            studentList.add(new Student(t,"name"+t,18+t,"phone"+t));
        }
        // 保存查詢到的結果(學生信息)到 request 域中
        req.setAttribute("stuList", studentList);
        // 請求轉發到 showStudent.jsp 頁面
        req.getRequestDispatcher("/showStudent.jsp").forward(req,resp);
    }

}
  • showStudent.jsp 頁面:
 <style>
        table{
            border: 1px blue solid;
            width: 600px;
            border-collapse: collapse;
        }
        td,th{
            border: 1px blue solid;
        }
    </style>
</head>
<body>
<%
    List<Student> studentList = (List<Student>) request.getAttribute("stuList");
%>
<table>
    <tr>
        <td>編號</td>
        <td>姓名</td>
        <td>年齡</td>
        <td>電話</td>
        <td>操作</td>
    </tr>
    <% for (Student student : studentList) { %>
    <tr>
        <td><%=student.getId()%></td>
        <td><%=student.getName()%></td>
        <td><%=student.getAge()%></td>
        <td><%=student.getPhone()%></td>
        <td>刪除、修改</td>
    </tr>
    <% } %>
</table>
</body>
</html>

Listener 監聽器

1,什麼是 Listener 監聽器?

①、Listener 監聽器它是 JavaWeb 的三大組件之一。JavaWeb 的三大組件分別是:Servlet 程序、Filter 過濾器、Listener 監聽器。

②、Listener 它是 JavaEE 的規範,就是接口。

③、監聽器的作用是,監聽某種事物的變化。然後通過回調函數,反饋給客戶(程序)去做一些相應的處理。

2,ServletContextListener 監聽器

  • ServletContextListener 它可以監聽 ServletContext 對象的創建和銷燬。

  • ServletContext 對象在 web 工程啓動的時候創建,在 web 工程停止的時候銷燬。

  • 監聽到創建和銷燬之後都會分別調用 ServletContextListener 監聽器的方法反饋

  • 兩個方法分別是:

public interface ServletContextListener extends EventListener {

    /**
     * 在 ServletContext 對象創建之後馬上調用,做初始化
     */
    void contextInitialized(ServletContextEvent sce);
    /**
     * 在 ServletContext 對象銷燬之後調用
     */
    void contextDestroyed(ServletContextEvent sce);

}
  • 如何使用 ServletContextListener 監聽器監聽 ServletContext 對象?
    使用步驟如下:

    1、編寫一個類去實現 ServletContextListener

    2、實現其兩個回調方法

    3、到 web.xml 中去配置監聽器

  • 監聽器實現類:

public class MyServletContextListenerImpl implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContextEvent對象被創建了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContextEvent對象被銷燬了");
    }
}
  • web.xml 中的配置:
<!-- 配置監聽器 -->
<listener>
    <listener-class>com.MyServletContextListenerImpl</listener-class>
</listener>

下一章,(10)可還記得那被遺忘的EL表達式和JSTL標籤庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章