目錄
- JSP概述
- 什么是 jsp
- Servlet 程式輸出 html 頁面
- 如何創建一個 jsp 動態頁面程式
- 如何修改 jsp 檔案的默認編碼
- jsp 的運行原理
- jsp 的語法
- jsp 檔案頭部宣告介紹(page 指令介紹)
- jsp 中的三種腳本介紹
- jsp 中的注釋
- jsp 九大內置物件
- jsp 四大域物件
- jsp中out輸出流和response.getwriter()輸出流
- jsp中out 和response的writer的區別演示
- out 流和 writer 流的兩個緩沖區如何作業
- jsp 的常用標簽
- 靜態包含--很常用
- 動態包含--很少用
- 頁面轉發--常用
- Listener 監聽器
- 什么是 Listener 監聽器
- ServletContextListener 監聽器
JSP概述
什么是 jsp
JSP(全稱 Java Server Pages)是由 Sun 公司專門為了解決動態生成 HTML 檔案的技術,
Servlet 程式輸出 html 頁面
在 jsp 技術之前,如果我們要往客戶端輸出一個頁面,我們可以使用 Servlet 程式來實作,具體的代碼如下:
public class HtmlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 設定回傳的資料內容的資料型別和編碼
response.setContentType("text/html; charset=utf-8");
// 獲取字符輸出流
Writer writer = response.getWriter();
//輸出頁面內容
writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\"http://www.w3.org/TR/html4/loose.dtd\">");
writer.write("<html>");
writer.write("<head>");
writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
writer.write("<title>Insert title here</title>");
writer.write("</head>");
writer.write("<body>");
writer.write("這是由 Servlet 程式輸出的 html 頁面內容!");
writer.write("</body></html>");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
}
}
在瀏覽器中輸入訪問 Servlet 的程式地址得到以下結果:

從上面的代碼可以發現,通過 Servlet 輸出簡單的 html 頁面資訊都非常不方便,
如果要輸出一個復雜頁面的時候,就更加的困難,而且不利于頁面的維護和除錯,
所以 sun 公司推出一種叫做 jsp 的動態頁面技術來實作對頁面的輸出繁鎖作業,
jsp 頁面的訪問不能像 HTML 頁面一樣拖到瀏覽器中,只能通過瀏覽器訪問 Tomcat 服務器再訪問 jsp 頁面,
如何創建一個 jsp 動態頁面程式
- 選中 Web 目錄,右鍵創建一個 jsp 檔案

-
輸入 jsp 頁面的檔案名

-
在 body 標簽中添加你想要顯示的文本內容

-
先啟動Tomcat服務器,
然后在瀏覽器中輸入 jsp 頁面的訪問地址,
jsp 頁面的訪問地址和 html 頁面的訪問路徑一樣 http://ip:埠號/工程名/檔案名
也就是 http://127.0.0.1:8080/Test/Demo.jsp 或 http://localhost:8080/Test/Demo.jsp(以自己的工程路徑為準)
如何修改 jsp 檔案的默認編碼
有些idea的默認編碼格式可能是GBK格式或者其他格式的,然后在JSP編碼時候可能會出現亂碼,修改為UTF-8格式可以避免亂碼,

注意事項:
1、jsp 頁面是一個類似于 html 的一個頁面, jsp 直接存放到 WebContent 目錄下,和 html 一樣
訪問 jsp 的時候,也和訪問 html 一樣
2、jsp 的默認編碼集是 iso-8859-1 修改 jsp 的默認編碼為 UTF-8
jsp 的運行原理
jsp的本質其實是一個Servlet程式,
首先我們去找到我們 Tomcat 的目錄下的 work\Catalina\localhost 目錄,
當我們新建Demo工程,并啟動 Tomcat
服務器后,我們發現
在 work\Catalina\localhost 目錄下多出來一個 JSPDemo目錄,

一開始目錄還是空目錄,
然后,我們在瀏覽器輸入一個 jsp 檔案的訪問路徑訪問,
比如 http://127.0.0.1:8080/JSPDemo/Demo.jsp訪問Demo.jsp 檔案
JSPDemo目錄馬上會生成 org\apache\jsp 目錄,
并且在會中有兩個檔案,

Demo_jsp.class 檔案很明顯是 index_jsp.java 源檔案編譯后的位元組碼檔案,
那么Demo_jsp.java 是個什么內容呢?
生成的 java 檔案名,是以原來的檔案名加上_jsp 得到, xxxx_jsp.java 檔案的名字
我們打開 Demo_jsp.java 檔案查看里面的內容:
發現,生成的類繼承于 HttpJspBase 類,這是一個 jsp 檔案生成 Servlet 程式要繼承的基類!!!

自動生成的java檔案繼承于HttpJspBase類
于是,關聯源代碼去查看一下 HttpJspBase 類的內容,從原始碼的類注釋說明中,發現HttpJspBase 這個類就是所有 jsp 檔案生成 Servlet 程式需要去繼承的基類,并且這個 HttpJspBase 類繼承于 HttpServlet 類,所以 jsp 也是一個 Servlet 小程式,

我們分別在工程的 Web 目錄下創建多個 jsp 檔案,然后依次訪問,它們都被翻譯為.java 檔案并編譯成為.class 位元組碼檔案

打開 Demo_jsp.java 檔案查看里面的內容可以發現,jsp 中的 html 頁面內容都被翻譯到 Servlet 中的 service
方法中直接輸出,

小結:
從生成的檔案我們不難發現一個規則,
a.jsp 翻譯成 java 檔案后的全名是 a_jsp.java 檔案
b.jsp 翻譯成 java 檔案后的全名是 b_jsp.java 檔案
么 那么 當我們訪問 個 一個 xxx.jsp 檔案后 成 翻譯成 java 檔案的全名是 xxx_jsp.java 檔案
xxx_jsp.java 檔案是一個 Servlet 程式,原來 jsp 中的 html 內容都被翻譯到 Servlet 類的 service 方法中原樣輸出,
jsp 的語法
jsp 檔案頭部宣告介紹(page 指令介紹)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
這是 jsp 檔案的頭宣告,表示這是 jsp 頁面,
| 屬性 | 含義 |
|---|---|
| language | 屬性值只能是 java,表示翻譯的得到的是 java 語言的 |
| contentType | 設定回應頭 contentType 的內容 |
| pageEncoding | 設定當前 jsp 頁面的編碼 |
| import | 給當前 jsp 頁面匯入需要使用的類包 |
| autoFlush | 設定是否自動重繪 out 的緩沖區,默認為 true |
| buffer | 設定 out 的緩沖區大小,默認為 8KB |
| errorPage | 設定當前 jsp 發生錯誤后,需要跳轉到哪個頁面去顯示錯誤資訊 |
| isErrorPage | 設定當前 jsp 頁面是否是錯誤頁面,是的話,就可以使用 exception 例外物件 |
| session | 設定當前 jsp 頁面是否獲取 session 物件,默認為 true |
| extends | 給服務器廠商預留的 jsp 默認翻譯的 servlet 繼承于什么類 |
jsp 中的三種腳本介紹
一、宣告腳本:
宣告腳本格式如下:
<%!
java 代碼
%>
在宣告腳本塊中,我們可以干 4 件事情
1.我們可以定義全域變數,
2.定義 static 靜態代碼塊
3.定義方法
4.定義內部類
幾乎可以寫在類的內部寫的代碼,都可以通過宣告腳本來實作
二、運算式腳本
運算式腳本格式如下:
<%=運算式 %>
運算式腳本 用于向頁面輸出內容,
運算式腳本 翻譯到 Servlet 程式的 service 方法中 以 out.print() 列印輸出
out 是 jsp 的一個內置物件,用于生成 html 的源代碼
注意:運算式不要以分號結尾,否則會報錯
運算式腳本可以輸出任意型別,
比如:
1.輸出整型
2.輸出浮點型
3.輸出字串
4.輸出物件
三、代碼腳本
代碼腳本如下:
<% java 代碼 %>
代碼腳本里可以書寫任意的 java 陳述句,
代碼腳本的內容都會被翻譯到 service 方法中,
所以 service 方法中可以寫的 java 代碼,都可以書寫到代碼腳本中
jsp 中的注釋
// 單行 java 注釋
/*
多行 java 代碼注釋
*/
單行注釋和多行注釋能在翻譯后的 java 源代碼中看見,
<%-- jsp 注釋 --%>
jsp 注釋在翻譯的時候會直接被忽略掉
<!-- html 注釋 -->
html 的注釋會被翻譯到 java 代碼中輸出到 html 頁面中查看
jsp 九大內置物件
我們打開翻譯后的 java 檔案,查看_jspService 方法,

通過原始碼可以發現 jsp 中九大內置物件分別是:
| 物件 | 含義 |
|---|---|
| request 物件 | 請求物件,可以獲取請求資訊 |
| response 物件 | 回應物件,可以設定回應資訊 |
| pageContext 物件 | 當前頁面背景關系物件,可以在當前背景關系保存屬性資訊 |
| session 物件 | 會話物件,可以獲取會話資訊 |
| exception 物件 | 例外物件只有在 jsp 頁面的 page 指令中設定 isErrorPage="true" 的時候才會存在 |
| application 物件 | ServletContext 物件實體,可以獲取整個工程的一些資訊 |
| config 物件 | ServletConfig 物件實體,可以獲取 Servlet 的配置資訊 |
| out 物件 | 輸出流 |
| page 物件 | 表示當前 Servlet 物件實體(無用,用它不如使用 this 物件) |
九大內置物件 , 都是我們可以在 【 代碼腳本 】 中或 【 運算式腳本 】 中直接使用的物件,
jsp 四大域物件
四大域物件經常用來保存資料資訊,
| 域物件 | 含義 |
|---|---|
| pageContext | 可以保存資料在同一個 jsp 頁面中使用 |
| request | 可以保存資料在同一個 request 物件中使用,經常用于在轉發的時候傳遞資料 |
| session | 可以保存在一個會話中使用 |
| application(ServletContext) | 就是 ServletContext 物件 |
四個作用域的測驗代碼:
新建兩個 jsp 頁面,分別取名叫:context1.jsp,context2.jsp
context1.jsp 的頁面代碼如下:
<%--
Created by IntelliJ IDEA.
User: Kohler
Date: 2022/8/26
Time: 20:00
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>context1</title>
</head>
<body>
這是 context1 頁面<br/>
<%
//設定 page 域的資料
pageContext.setAttribute("key", "pageContext-value");
//設定 request 域的資料
request.setAttribute("key", "request-value");
//設定 session 域的資料
session.setAttribute("key", "session-value");
//設定 application 域的資料
application.setAttribute("key", "application-value");
%>
<%-- 測驗當前頁面作用域 --%>
<%=pageContext.getAttribute("key") %><br/>
<%=request.getAttribute("key") %><br/>
<%=session.getAttribute("key") %><br/>
<%=application.getAttribute("key") %><br/>
<%
// 測驗 request 作用域
// request.getRequestDispatcher("/context2.jsp").forward(request, response);
%>
</body>
</html>
context2.jsp 的頁面代碼如下:
<%--
Created by IntelliJ IDEA.
User: Kohler
Date: 2022/8/26
Time: 20:03
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>context2</title>
</head>
<body>
這是 context2 頁面 <br/>
<%=pageContext.getAttribute("key") %><br/>
<%=request.getAttribute("key") %><br/>
<%=session.getAttribute("key") %><br/>
<%=application.getAttribute("key") %><br/>
</body>
</html>
測驗 pageContext 作用域:
直接訪問 context1.jsp 檔案,結果:

測驗 request 作用域:
1.在 context1.jsp 檔案中添加轉發到 context2.jsp(有資料)
2.直接訪問 context2.jsp 檔案 (沒有資料)
測驗 session 作用域:
1.訪問完 context1.jsp 檔案
2.關閉瀏覽器,但是要保持服務器一直開著
3.打開瀏覽器,直接訪問 context2.jsp 檔案
測驗 application 作用域:
1.訪問完 context1.jsp 檔案,然后關閉瀏覽器
2.停止服務器,再啟動服務器,
3.打開瀏覽器訪問 context2.jsp 檔案


context1.jsp頁面中:
context1頁面的pageContent的值成為null了,因為添加轉發跳轉到了另一個jsp頁面
request還有值是因為,雖然跳轉到了另一個頁面但是這還屬于一次請求,
context1和context2中session還有值是因為當前都是在一個瀏覽器中訪問,換一個瀏覽器的結果:

application一直有值是因為當前tomcat一直在一次運行中,如果重新部署或者重啟服務器就會變為null
重啟服務器:

jsp中out輸出流和response.getwriter()輸出流
jsp中out 和response的writer的區別演示
<%--
Created by IntelliJ IDEA.
User: Kohler
Date: 2022/8/26
Time: 20:41
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>output</title>
</head>
<body>
<%
// out 輸出
out.write("這是 out 的第一次輸出<br/>");
// out flush 之后,會把輸出的內容寫入 writer 的緩沖區中
out.flush();
// 最后一次的輸出,由于沒有手動 flush,會在整個頁面輸出到客戶端的時候,自動寫入到 writer 緩沖區
out.write("這是 out 的第二次輸出<br/>");
// writer 的輸出
response.getWriter().write("這是 writer 的第一次輸出<br/>");
response.getWriter().write("這是 writer 的第二次輸出<br/>");
%>
</body>
</html>
在瀏覽器里輸入 http://localhost:8080/JSPDemo/output.jsp運行查看的結果:

out 流和 writer 流的兩個緩沖區如何作業

jsp 的常用標簽
<%-- 靜態包含 --%>
<%-- 動態包含 --%>
<%-- 轉發 --%>
靜態包含--很常用
<%@ include file="" %>
靜態包含是把包含的頁面內容原封裝不動的輸出到包含的位置,
動態包含--很少用
<jsp:include page=""></jsp:include>
動態包含會把包含的 jsp 頁面單獨翻譯成 servlet 檔案,然后在執行到時候再呼叫翻譯的 servlet 程式,并把
計算的結果回傳,
動態包含是在執行的時候,才會加載,所以叫動態包含,
頁面轉發--常用
<jsp:forward page=""></jsp:forward>
<jsp:forward 轉發功能相當于
request.getRequestDispatcher("/xxxx.jsp").forward(request, response); 的功能,
| 靜態包含 | 動態包含 | |
|---|---|---|
| 是否生成 java 檔案 | 不生成 | 生成 |
| service 方法中的區別 | 把包含的內容原封拷貝到 service 中 | JspRuntimeLibrary.include 方法 |
| 是否可以傳遞引數 | 不能 | 可以 |
| 編譯次數 | 1 | 包含的檔案 + 1 |
| 適用范圍 | 適用包含純靜態內容(CSS,HTML,JS),或沒有;非常耗時操作,或大量 java 代碼的 jsp | 包含需要傳遞引數,含有大量 java 代碼,運算,耗時很長的操作, |
補充:
在作業中,幾乎都是使用靜態包含,理由很簡單,因為 jsp 頁面雖然可以寫 java 代碼,做其他的功能操作,但是由于 jsp 在開發程序中被定位為專門用來展示頁面的技術,也就是說,jsp 頁面中,基本上只有 html,css,js,還有一些簡單的 EL,運算式腳本等輸出陳述句,所以我們都使用靜態包含,
Listener 監聽器
什么是 Listener 監聽器
什么是監聽器?監聽器就是實時監視一些事物狀態的程式,我們稱為監聽器,
就好像朝陽群眾?朝陽區只要有哪個明星有什么不好的事,他們都會知道,然后舉報,
那么朝陽群眾就是監聽器,明星就是被監視的事物,舉報就是回應的內容,
又或者說是,電動車的報警器,當報警器鎖上的時候,我們去碰電動車,電動車就會報警,
報警器,就是監聽器,電動車就是被監視的物件,報警就是回應的內容,
ServletContextListener 監聽器
javax.servlet.ServletContextListener ServletContext 監聽器
監聽器的使用步驟,
第一步:我們需要定義一個類,然后去繼承生命周期的監聽器介面,
第二步:然后在 Web.xml 檔案中配置,
ServletContextListener 監聽器,一定要在 web.xml 檔案中配置之后才會生效
<listener>
<listener-class>全類名</listener-class>
</listener>
生命周期監聽器兩個方法:
public void contextInitialized(ServletContextEvent sce) 是 ServletContext 物件的
創建回呼
public void contextDestroyed(ServletContextEvent sce) 是 ServletContext 物件的銷
毀回呼
以 ServletContext 的監聽器為例:
創建一個 ServletContextListenerImpl 類實作 ServletContextListener 介面,
package com.kailong.servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServletContextListenerImpl implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext 物件被創建了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext 物件被銷毀了");
}
}
在 web.xml 檔案中的配置如下:
<listener>
<listener-class>com.kailong.servlet.ServletContextListenerImpl</listener-class>
</listener>
這個時候,啟動 web 工程和正常停止 web 工程,后臺都會如下列印:

如圖片失效等情況請參閱公眾號文章:https://mp.weixin.qq.com/s/jWej5-yDpj6DZJz_saYZ_Q
歡迎關注公眾號:愚生淺末

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/502887.html
標籤:Java
下一篇:冪等公共組件
