JavaServer Pages
基於java語言實現的服務器端頁面
JSP是JavaEE規範之一
JSP文件後綴默認是.jsp,但是jsp文件的後綴也可以修改的,通過修改CATALINA_HOME/conf/web.xml文件
JS : JavaScript,運行在瀏覽器中,和服務器沒有關係,和java也沒有關係
JSP : JavaServer Pages,運行在服務器中,JSP底層就是java程序,運行在JVM中。
JSP的執行原理:
- 瀏覽器上訪問的路徑雖然是以.jsp結尾,訪問的是某個jsp文件,其實底層執行的是jsp對應的java程序
- Tomcat服務器負責將.jsp文件翻譯生成.java源文件,並且將java源文件編譯生成.class字節碼文件
- 訪問jsp,其實底層還是執行了.class文件中的程序。
- Tomcat服務器內置了一個JSP翻譯引擎,專門負責翻譯JSP文件,編譯java源文件
- index.jsp會被翻譯生成index_jsp.java,編譯生成index_jsp.class
- index_jsp這個類繼承了HttpJspBase,而HttpJspBase繼承了HttpServlet
- jsp就是Servlet,只不過職責不同,JSP的強項做頁面展示。
在JSP文件中編寫的所有的HTML、CSS、JavaScript,對於JSP來說,只是普通的字符串。被翻譯到:out.write("翻譯到這裏");
JSP文件修改之後,不需要重新部署,也不需要重新啓動Tomcat服務器。
JSP文件第一次訪問的時候爲什麼非常慢?
- 啓動JSP翻譯引擎
- 需要一個翻譯的過程
- 需要一個編譯的過程
- 需要Servlet對象的創建過程
- init方法調用
- service方法調用.....
爲什麼第2+次訪問JSP的時候非常快?
- 不需要重新翻譯
- 不需要重新編譯
- 不需要創建Servlet對象
- 直接調用Servlet對象的service方法
JSP也是單實例多線程環境下運行的一個Servlet對象。
JSP文件在被修改之後會被重新翻譯,Tomcat服務器會記錄JSP文件的最後修改時間。
關於JSP的小腳本scriptlet:
<%----%> JSP的專業註釋,使用這種註釋方式,不會被翻譯到java源文件中
<%
java語句;
java語句;
java語句;
%>
小腳本中的java語句被翻譯到Servlet的service方法中,所以小腳本中必須編寫“java語句”,java語句以分號結尾。
JSP的聲明語法格式:
<%!
實例變量;
靜態變量;
方法;
靜態語句塊;
構造函數;
.....
%>
注:
聲明塊中的java程序會被JSP翻譯引擎翻譯到service方法之外
聲明塊中不能直接編寫java語句,除非是變量的聲明
<% out.print(); %> 等同於 <%= %>
<%=i %> 表達式語法,具有輸出功能,輸出到瀏覽器上
關於JSP的九大內置對象:
1、內置對象可以直接在JSP文件中拿來使用。
2、九大內置對象
內置對象 完整類名
----------------------------------------------------------------------------
pageContext javax.servlet.jsp.PageContext 頁面範圍【頁面上下文】
request javax.servlet.http.HttpServletRequest 請求範圍
session javax.servlet.http.HttpSession 會話範圍
application javax.servlet.ServletContext 應用範圍
response javax.servlet.http.HttpServletResponse 響應對象
out javax.servlet.jsp.JspWriter 標準輸出流
config javax.servlet.ServletConfig Servlet配置信息對象
exception java.lang.Throwable 異常引用(isErrorPage="true")
page javax.servlet.http.HttpServlet (page = this) 很少用
3、以上內置對象只能在service方法中“直接”使用,在其它方法中無法“直接”使用,可以間接使用。
從小到大依次爲:
pageContext < request < session < application
pageContext : 在同一個JSP頁面中共享數據,不能跨JSP頁面
request : 在同一個請求中共享數據 【使用較多】
session : 在同一個會話中共享數據 【使用較多】
application : 所有用戶共享的數據可以放到應用範圍中
pageContext只能在同一個JSP頁面中共享數據。範圍是最小的。
通過pageContext這個頁面上下文對象,可以獲取當前頁面中的其它對象。
<%=pageContext.getRequest() %>
<%=pageContext.getSession() %>
<%=pageContext.getServletContext() %>
<%=pageContext.getServletConfig() %>
pageContext對象傳遞數據:
pageContext.setAttribute(“username”,jack); //存
pageContext.getAttribute(“username”); //取
只能存儲一個頁面中的數據,無法跨頁面。可以獲取include指令包含的jsp頁面中存儲的數據,但是不能獲取include動作包含的jsp頁面中存儲的數據。
使用pageContext對象往request,session,application對象中存儲數據。
向request範圍存儲數據:
pageContext.setAttribute(“username”,”jack”,PageContext.REQUEST_SCOPE);
向session範圍存儲數據:
pageContext.setAttribute(“username”,”jack”,PageContext.SESSION_SCOPE);
向application範圍存儲數據:
pageContext.setAttribute(“username”,”jack”,PageContext.APPLICATION_SCOPE);
關於JSP的指令:
1、指令的作用,是指導JSP的翻譯引擎如何翻譯JSP代碼。
2、JSP中共三個指令:
* page 頁面指令
* include 包含指令
* taglib 標籤庫指令
3、指令的使用語法格式:
<%@指令名 屬性名=屬性值 屬性名=屬性值.....%>
4、關於JSP的page指令,page指令中常用的屬性:
* contentType 設置JSP的響應內容類型,同時在響應的內容類型後面也可以指定響應的字符編碼方式
* pageEncoding 設置JSP響應時的字符編碼方式
* import 組織導入
* session 設置當前JSP頁面中是否可以直接使用session內置對象
* errorPage 錯誤頁面
* isErrorPage 是否是錯誤頁面
* isELIgnored 是否忽略EL表達式
關於page指令中的session屬性:
- session="true"
* 表示在當前JSP中可以直接使用內置對象session
* 程序執行的時候獲取當前的session會話對象,若獲取不到則新建session對象
- session="false"
* 表示在當前JSP中不能直接使用內置對象session
* 但是有一些業務可能要求在當前JSP頁面中獲取當前的session對象,沒有獲取到則不新建session對象,此時需要編寫 以下程序
* <%@page contentType="text/html; charset=UTF-8" session="false"%>
* <%
* HttpSession session = request.getSession(false);
* %>
- 若session這個屬性沒有指定,默認值就是session="true"
關於page指令的errorPage屬性:
當前JSP頁面出錯之後,要跳轉的頁面路徑,需要使用該屬性指定。
關於page指令中的isErrorPage屬性:
- 用於錯誤頁面
- isErrorPage = "false" 表示內置對象exception無法使用【缺省情況下是false】
- isErrorPage = "true" 表示內置對象exception可以使用
* <%-- 使用內置對象exception打印異常堆棧追蹤信息 --%>
* <%-- exception引用指向了拋出的異常 --%>
* <%
* exception.printStackTrace();
* %>
例:<%@page contentType="text/html; charset=UTF-8" session="true" errorPage="/error.jsp"%>
<%@page contentType="text/html" %>
<%@page pageEncoding="UTF-8" %>
<%@page import="java.util.Date" %>(光標至於類名末尾,alt+/快捷導入)
關於include指令:
1、a.jsp可以將b.jsp包含進來,當然被包含的資源不一定是jsp,也可能是其它的網絡資源
2、include作用:
在網頁中有一些主體框架,例如:網頁頭、網頁腳,這些都是固定不變的,
我們可以將網頁頭、網頁腳等固定不變的單獨編寫到某個JSP文件中,
在需要頁面使用include指令包含進來。
優點:
代碼量少了
便於維護【修改一個文件就可以作用於所有的頁面】
3、在一個jsp中可以使用多個include指令
4、include實現原理:
4.1 編譯期包含
4.2 a.jsp包含b.jsp,底層共生成一個java源文件,一個class字節碼文件,翻譯期包含/編譯期包含/靜態聯編
5、靜態聯編的時候,多個jsp中可以共享同一個局部變量。
因爲最終翻譯之後service方法只有一個。
例:<%@include file="/index2.jsp" %>
關於JSP中的動作:
語法格式:<jsp:動作名 屬性名=屬性值 屬性名=屬性值....></jsp:動作名>
關於JSP中的forward動作:
<jsp:forward page="/index2.jsp"></jsp:forward>
關於JSP中的include動作:
1、a.jsp包含b.jsp,底層會分別生成兩個java源文件,兩個class字節碼文件
2、編譯階段並沒有包含,編譯階段是兩個獨立的class字節碼文件,生成兩個Servlet,兩個獨立的service方法
3、使用include動作屬於運行階段包含, 實際上是在運行階段a中的service方法調用了b中的service方法,達到了包含效果
4、a.jsp包含b.jsp,若兩個jsp文件中有重名的變量,只能使用動態包含。其餘都可以使用靜態包含。
5、include動作完成的動態包含,被稱爲動態聯編。
例:<jsp:include page="/b.jsp"></jsp:include>