Web容器(Servlet引擎)接收到.jsp爲擴展名的URL訪問請求時,它將把該訪問請求交給JSP引擎去處理,JSP引擎負責解釋和執行JSP頁面。java
當Web容器接收到客戶端的訪問請求時,它將根據請求的URL在web.xml配置文件中查找匹配<servlet-mapping>元素,而後將請求交給元素中指定的servlet程序去處理,打開Tomcat下conf\web.xml文件能夠發現以.jsp爲擴展名的訪問請求實際由JspServlet負責處理。web
每一個JSP頁面在第一次被訪問時,JSP引擎將它翻譯成一個Servlet源程序,接着再把這個Servlet源程序編譯成Servlet的class文件,而後再由Servlet引擎像調用普通Servlet程序同樣的方式來裝載和解釋執行這個由JSP頁面翻譯成的servlet程序。api
將JSP頁面翻譯成Servlet程序後再運行的機制有一個明顯的好處,那就是JSP引擎僅須要將JSP頁面翻譯爲Servlet程序,而與客戶端的交互過程仍然由Servlet引擎來處理,重複利用了已有的Servlet引擎技術。數組
print系列方法可將各類類型的數據轉換成字符串的形式輸出;write系列方法只能輸出字符、字符數組和字符串等與字符相關的數據。瀏覽器
在<%= %>的表達式至關於在<% %>使用out.printl()方法。緩存
JSP提供了9個預先定義的變量,這些變量也被稱爲隱式對象,某些書籍則稱爲JSP內部對象。這9個隱式對象分別是:session
config,ServletConfig類型的實例對象app
application,ServletContext類型的實例對象jsp
request,做爲_jspService(能夠認爲就至關於HttpServlet中的service方法)方法的參數(HttpServletRequest request)傳遞進來的this
response,做爲_jspService方法的參數(HttpServletResponse response)傳遞進來的
session,HttpSession的實例對象
page,對象的類型爲Object,它被賦值爲this,即表明JSP頁面所編譯成的Servlet對象自身,當前用處不大
exception,該對象只能在處理錯誤的JSP頁面中使用,後面講解
以及——
out對象
pageContext對象
out對象是經過調用pageContext對象的getOut方法返回的,其做用及用法與ServletResponse.getWriter方法返回的PrintWriter對象很是類似,但out隱式對象類型爲JspWriter,JspWriter至關於一種帶緩存功能的PrintWriter,設置page指令的buffer屬性能夠調整它的緩存大小,甚相當閉它的緩存。
只有向out對象中寫入了內容,且知足如下任何一個條件,out對象纔會去調用ServletResponse.getWriter方法,並經過該方法返回的PrintWriter對象將out對象的緩衝區中的內容真正寫入到Servlet引擎提供的緩衝區中:
設置page指令的buffer屬性關閉了out對象的緩存功能
寫入到out對象中的內容充滿了out對象的緩衝區
JSP頁面結束
(1)
<% out.println("first line<br>"); response.getWriter().println("second line<br>"); %>
用瀏覽器訪問,發現顯示結果爲:
second line
first line
這是由於out.println語句只是把內容寫入到了out對象的緩衝區中,直到整個JSP頁面結束時,out對象才把它的緩衝區裏面的內容真正寫入到Servlet引擎提供的緩衝區中,而response.getWriter.println語句則是真正把內容寫入到Servlet引擎提供的緩衝區中。
(2)
<% ServletOutputStream sos = response.getOutputStream(); sos.println("www.baidu.com"); %>
若是在<%前面或最後的%>後面輸入了任意字符,訪問該JSP頁面會報異常。由於位於JSP腳本元素以外的任何字符文本,在JSP頁面所翻譯成的Servlet程序中以out.write方法輸出到客戶端。因爲只要向out對象寫入了內容,它就會在JSP頁面結束時調用getWriter方法,這就與getOutputStream方法發生了衝突。
(這裏就知道jsp-api包是幹什麼的?若是沒有這個包,jsp頁面根本不認識pageContext這個預約義對象)
pageContext對象封裝了當前JSP頁面的運行信息,它提供了返回JSP頁面的其餘隱式對象的方法。PageContext類中定義了一個setAttribute方法來將對象存儲進pageContext對象內部的一個HashMap對象中,同時定義了一個getAttribute方法來獲取存儲在HashMap對象中的對象,以便在JSP頁面與調用的普通Java類之間傳遞對象信息。PageContext除了能夠存儲和檢索自身的屬性對象外,還定義了能夠檢索其餘域範圍內的屬性對象的方法。
(1)、得到其餘隱式對象:
getException
getPage
getRequest
getResponse
getServletConfig
getServletContext
getSession
getOut
(2)、引入和跳轉到其餘資源
PageContext類中定義了一個forward和兩個include方法來簡化和替代RequestDispatcher.forward方法和RequestDispatcher.include方法的調用,完整定義爲:
public void forward(String relativeUrlPath) throws ...Exception public void include(String relativeUrlPath) throws ...Exception public void include(String relativeUrlPath, boolean flush) throws ...Exception
傳遞給這些方法的資源路徑都只能是相對路徑,若是路徑以「/」開頭,表示相對於當前Web應用程序的根目錄,不然表示相對於當前JSP所映射的訪問路徑。
第一個include方法在引入資源前先將out對象中的內容刷新到Servlet引擎提供的緩衝區中;第二個include方法則經過一個參數來決定在引入資源前是否刷新out對象中的內容。
forward方法在將請求轉發給其餘資源以前,先清空out對象中已寫入的內容,而後調用RequestDispatcher.forward方法執行請求轉發。
(3)訪問各個域範圍的屬性
在application、session、request、pageContext對象中均可以調用setAttribut方法和getAttribute方法來設置和檢索屬於各自域範圍內的屬性。存儲在application對象中的屬性能夠被同一個Web應用程序中的全部Servlet和JSP頁面訪問;存儲在session對象中的屬性能夠被屬於同一個會話的全部Servlet和JSP頁面訪問;存儲在request對象中的屬性能夠被屬於同一個請求的全部Servlet和JSP頁面訪問。存儲在pageContext對象中的屬性僅能夠被當前JSP頁面的當前響應過程(下次響應則不一樣)的各個組件訪問。
此外,PageContext類中還提供了對各個域範圍的屬性進行統一管理的方法。
setAttribute方法
兩種重載形式:
setAttribute(String name, Object o) // 默認把對象存儲在page域範圍(就是存儲到pageContext對象)中
setAttribute(String name, Object o, int scope) //scope表示把對象存儲進指定的域範圍,PageContext定義了4個整數常量,分別是APPLICATION_SCOPE,SESSION_SCOPE,REQUEST_SCOPE,PAGE_SCOPE
getAttribute方法(兩種)
removeAttribute方法(兩種)
findAttribute方法
用於依次從page、request、session、application域範圍查找某個指定名稱的屬性,找到則返回指定對象,不然返回null。