今天主要學習JSP基礎
思維導圖:
一.JSP的概念:
JSP的全名是Java Server Pages,他的一個建立在Servlet的規範上推出一個動態網頁的開發技術,在JSP上,HTML代碼可以和Java代碼共同存在。其中html代碼負責的是網頁的靜態內容,java代碼負責是網頁的動態內容,爲了區分他和html的區別,所以命名爲jsp,其實jsp本質上不是一個網頁而是一個java類。
二.JSP執行原理:
JAVA代碼和我們的HTML代碼的混合運行,既然可以在JSP頁面直接去寫Java代碼,那麼我們之前學的Servlet還有存在的意義嗎?兩種是互補行爲,不是取代行爲。
1.瀏覽器訪問了服務器的demo.jsp
2.Tomcat會根據URL去尋找你的jsp
3.會將找到的jsp加載到Tomcat當中
4.Tomcat會將這個jsp翻譯成一個Java文件
(Tomcat會調用org.apache.jasper.runtime.HttpJspBase這個類文件,對我們的jsp進行編譯其實HttpJspBase這個類除了可以對jsp進行編譯,同時還繼承了HttpServlet,那麼也就意味着我之前說過的一句話(Servlet的所有技術都是適用在JSP的/JSP也是一個建立在Servlet標準的基礎上進行開發)所以說,JSP不單單可以寫HTML代碼,可以寫Java代碼,甚至還可以直接編寫Servlet的實現代碼)
5.翻譯成java文件之後(_demo_jsp.java),然後會對這個文件進行編譯(_demo_jsp.class)
6.Tomcat就會去調用這個類
【tomcat自動調用,無法干預(Eclipse的存儲位置在tomcat/work/..、IDEA的存儲位置在C:\Users\IntellijIdeaxxx\system\tomcat\xxx...)】
7.輸出到瀏覽器
(所謂的輸出到瀏覽器,就是內部將一個靜態HTML使用out.write()的方式進行寫出,Java代碼就按照正常類方式進行處理)
8.總結:
(1)jsp之所以能夠編寫HTML代碼,其實本質上也是依靠類似於我們Servlet的response.getWriter().println()方法進行輸出的
(2)jsp之所以能夠直接的使用request,不用像我們之前寫Servlet的時候那樣去繼承然後重寫doGet,是因爲HttpJspBase這個類從一開始就已經繼承了HttpServlt並且實現了service等方法
三.編譯的過程(JSP的生命週期):
1.翻譯成java文件
2.編譯成class文件
3.執行構造方法
4.執行_jspInit方法,完成的JSP的初始,順便完成Servlet的初始化
5.執行_jspService方法,跟Servlet的邏輯一致
6.執行_jspDestroy方法,在本JSP完全結束後銷燬
四.JSP的語法:
1.註釋:
(1)JSP註釋:
<%-- 我是一個JSP的註釋 --%>
(2)HTML註釋:
<!-- 我是一個HTML的註釋 -->
(3)結論:
這兩個註釋都會正常生效,但是HTML代碼的註釋 會直接顯示在瀏覽器當中(瀏覽器是可以讀到只是不執行)而JSP的註釋,瀏覽器不會讀、也不會執行,也就意味 JSP的註釋比HTML的註釋更加的安全,如果你不想讓用戶看到你的註釋內容,建議使用JSP的註釋。
2.如何在JSP當中書寫我們的java代碼:
(1)JSP的動態輸出:
<%= 輸出的內容 %>
作用:就是向頁面輸出一些內容,但是這裏的語句必須是有返回值的只要在System.out.print()能夠輸出的內容,他可以輸出。
原理:其實就是調用了out.print()這個方法
(2)JSP的代碼腳本:
<% java代碼 %>
作用:可以在這裏面編寫任意的Java代碼,作用域跟我們之前寫的Java類是完全一致的(編寫除成員方法之外的所有代碼)
原理:會通過tomcat翻譯成一個java文件,在編譯成class文件,這裏是不能書寫成員方法
3.JSP的變量聲明:
<%! 變量或者方法 %>
作用:用於生成一個成員變量和成員方法(只能編寫成員變量和成員方法)
原理:就是編譯的時候,將這裏的代碼聲明在成員位置
4.在頁面輸出10次hello(是頁面不是控制檯):
其實在頁面當中,java腳本是可以拆分執行,比如下面
<%for (int i = 0; i < 10; i++) {%>
<span>hello</span><br/>
<%}%>
但是一般千萬不要這樣去執行,因爲會導致前端和後端都不看懂代碼,以後會有一些表達式幫我們解決這樣的問題。
5.JSP的指令:
JSP指令是一個爲JSP引擎設計的一個用於設置JSP內容的一個屬性(有點類似我們之前在HTML裏面學的head是差不多)這裏面的內部並不會輸出或顯示在頁面,只是處理JSP一些設置性的東西。
6.JSP指令的語法:
<%@ 指令名 屬性名="值"%>
舉例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
注意:
因爲這個指令本質還是一些Java代碼的設置的,所以會有一定程度上的大小寫敏感問題,注意下這個問題
7.JSP指令的分類:
在JSP2.0版本當中,提供三個指令,page、include、taglib。每一個指令都有自己獨立的語法和屬性設置。
(1)page:
<%@ page
language="java"
import="java.util.*"
import="java.util.*"
session="true"
buffer="8kb"
errorPage="/error.jsp"
isErrorPage="true"
pageEncoding="utf-8"
contentType="text/html;charset=UTF-8"
isELIgnored="true"
%>
language="java":告訴服務器以一個什麼樣的編程語言來解析文件的內容
import="java.util,*":跟我們之前寫java代碼導包是一樣的,如果是多個包的導入使用逗號分隔
session="true":控制當前頁面是否開啓一個session,如果是true則代表開啓,其實本質上就是去調用了一個session的對象使用
buffer="8kb":控制當前頁面的緩衝區大小(跟我們之前學的BufferedWriter是一致的),jsp頁面裏面的內容並不會立即的輸出到頁面當中,而是等頁面的緩衝大小達到指定大小,或者關閉或者加載完畢之後,纔會輸出。
errorPage="/error.jsp"當頁面發生異常的時候,轉發到的指定的頁面。(一般不太常用,因爲每一個頁面都需要去寫,而且沒有辦法根據不同的錯誤狀態轉發到不同的頁面顯示)建議在web.xml裏面配置一個全局的錯誤跳轉
<error-page>
<error-code>錯誤狀態碼1</error-code>
<location>/需要跳轉的頁面(可以是本地,也可以是網址)</location>
</error-page>
<error-page>
<error-code>錯誤狀態碼2</error-code>
<location>/需要跳轉的頁面(可以是本地,也可以是網址)</location>
</error-page>
isErrorPage="true":是否指定當前頁面爲錯誤顯示頁面,如果指定則會在發生錯誤之後,直接在本頁面顯示一個錯誤信息(調用了一個exception對象)否則不會創建(默認的操作的就是這個)
pageEncoding="utf-8":設置當前頁面的內容以什麼樣的字符集編碼翻譯成java類
contentType="text/html;charset=UTF-8":設置當前頁面的內容以什麼樣的字符集編碼傳輸到瀏覽器(跟我們之前寫Servlet的時候,設置的response.setContentType("text/html;charset=UTF-8")完全一致的也就意味的,如果設置了這個屬性,在JSP頁面當中凡是響應給瀏覽的內容就不需要單獨設置字符集了)
isELIgnored="true":設置頁面是否忽略EL表達式
(2)include:
<%@ include
file="header.jsp
"%>
include指令主要是用於通知JSP在翻譯本頁面的同時,也去翻去其他被導入的文件,並且合併在同一個頁面進行執行;一個頁面當中,嵌套包含另外一個頁面,這種又被稱之爲靜態導入[包含](可以動態資源,也可以是靜態資源)
(3)taglib:暫時不講,後面馬上講到。
五.JSP的內置(隱藏)九大對象:
重要:
(1)HttpServletRequest request:請求對象,其實用的就是Servlet的,原理一致[作用域]
(2)HttpServletResponse response:響應對象,其實用的就是Servlet的,原理一致
(3)ServletContext application:上下文對象,其實用的就是Servlet的,不過改了個名字 叫做application(Servlet叫做ServletContext)[作用域]
(4)ServletConfig config:配置對象,其實用的就是Servlet的,其實用的就是Servlet的
(5)HttpSession session:會話作用域,用於一個會話數據存儲[作用域]
瞭解:
(6)PageContext pageContext:JSP作用域,這個作用域只能在本jsp當中有效[作用域]【因爲這九大對象都是隱藏的,JSP直接調用的,如果想獲取這九大對象的具體實例,可以通過如下方法獲取】
//返回的是頁面輸出一些異常信息對象(默認的錯誤頁面其實就是他調用的)
pageContext.getException();
//返回的paga對象(可以理解一個Object對象)
pageContext.getPage();
//返回的是一個在本JSP當中生效的一個請求對象
ServletRequest request1 = pageContext.getRequest();
//返回的是一個在本JSP當中生效的一個響應對象
pageContext.getResponse();
//返回的是一個在本JSP當中生效的一個Servlet配置對象
pageContext.getServletConfig();
//返回的是一個在本JSP當中生效的一個ServletContext上下文對象
pageContext.getServletContext();
//返回的是一個在本JSP當中生效的一個Session對象
pageContext.getSession();
//返回的是一個在本JSP當中生效的一個JspWriter對象
pageContext.getOut();
(7)JspWriter out:用於jsp輸出的對象,<%= %>就是使用的這個對象
(8)Object page:其實就是一個本頁面的對象,或者可以理解爲調用了Object的方法
(9)Throwable exception:異常輸出對象,用於JSP頁面的異常輸出
六. JSP的四大作用域:
我們要知道,在Servlet當中一共有三個作用域(request/servletContext/session)。但是JSP不但實現的Servlet的三大作用域,自己還有一個特有的pageContext作用域,也就是說Servlet有三大作用域,而JSP有四大作用域。
四大作用域的比較:
(1)pageContext(JSP作用域):
作用範圍:只在當前JSP頁面當中有效
開始時間:頁面被加載的時候
結束時間:頁面刷新或者離開
(2)request(請求作用域):
作用範圍:在一個請求(鏈)當中有效
開始時間:收到請求
結束時間:響應完畢
(3)session(會話作用域):
作用範圍:同一個會話當中有效
開始時間:會話開始
結束時間:會話結束
(4)application(上下文作用域):
作用範圍:在一個Web項目當中有效
開始時間:項目被運行
結束時間:項目被結束
pageContext:
添加數據:
pageContext.setAttribute("name","toobug");
添加數據到指定作用域:
pageContext.setAttribute("age",10,pageContext.REQUEST_SCOPE);
pageContext不但可以將數據保存到page域,同樣也可以保存到其他域
PAGE_SCOPE:默認,JSP作用域
REQUEST_SCOPE:請求作用域
SESSION_SCOPE:會話作用域
APPLICATION_SCOPE:全局作用域
獲取數據:
pageContext.getAttribute("name");
從指定作用域獲取數據:
pageContext.getAttribute("age",pageContext.REQUEST_SCOPE);
PAGE_SCOPE:默認,JSP作用域
REQUEST_SCOPE:請求作用域
SESSION_SCOPE:會話作用域
APPLICATION_SCOPE:全局作用域
搜索作用域:
pageContext.findAttribute("name");
在JSP的四個作用域當中,去尋找一個叫做name的數據,默認從小到大去尋找,一旦找到就返回
移除作用域:
pageContext.removeAttribute("name");
移除其他作用域的數據
pageContext.removeAttribute("name",pageContext.REQUEST_SCOPE);
總結:
<1>作用域從小到大的排序應該是pageContext < request < session < application在實際開發當中,最小和最大的我們一般都不太常用,特別是pageContext。
<2>pageContext:作用域範圍太小,沒有轉發 也就意味着存儲的數據永遠只能在一個頁面當中
<3>application:作用域範圍太大,一個WEB當中,可能有無數個Servlet,也可以有無數個程序員一個數據存到application當中,作用範圍太大 就不能保證你數據的穩定性,很有可能被其他程序員無意篡改或者衝突。
<4>JSP的基礎:
JSP的執行原理(寫個JSP代碼->翻譯->編譯->執行)
JSP的語法(JSP的表達式,JSP的輸出,JSP的聲明)
JSP的九大內置對象(筆記看)
JSP的四大作用域(筆記看,Servlet只有三大作用域)
JSP的三大指令(include,page,taglib)
JSP和Servlet的工作區別:(重點)
JSP:負責將Servlet的結果轉換爲一個頁面動態數據的展示
Servlet:負責從JSP將數據取到後端
<5>注意:雖然我們現在學到了JSP,但是我們仍然不建議太廣泛去使用JSP。因爲JSP裏面不但嵌套了前端代碼,也嵌套了JAVA代碼,也就造成了前端和後端混合開發在前端代碼裏面寫上太多的JAVA代碼其實是不明智的,你看不懂前端,前端也看不懂後端。在以後,我們會慢慢的將前端和後端進行代碼的分離(前後端分離開發)。