一.JSP運行原理 每個JSP 頁面在第一次被訪問時,WEB容器都會把請求交給JSP引擎(即一個Java程序)去處理。JSP引擎先將JSP翻譯成一個_jspServlet(實質上也是一個servlet) ,然後按照servlet的調用方式進行調用。 由於JSP第一次訪問時會翻譯成servlet,所以第一次訪問通常會比較慢,但第二次訪問,JSP引擎如果發現JSP沒有變化,就不再翻譯,而是直接調用,所以程序的執行效率不會受到影響。 JSP引擎在調用JSP對應的_jspServlet時,會傳遞或創建9個與web開發相關的對象供_jspServlet使用。JSP技術的設計者為便於開發人員在編寫JSP頁面時獲得這些web對象的引用,特意定義了9個相應的變量,開發人員在JSP頁面中通過這些變量就可以快速獲得這9大對象的引用。 這9個對象分別是哪些,以及作用也是筆試經常考察的知識點。 注:JspAPI在線查看 二.九大隱式對象 1.哪九大隱式對象?? 如下圖所示: Request Response Session Application servletContext Config servletConfig Page this Exception Out jspWriter pageContext 為什麼叫隱式對象?個人感覺是因為在jsp中內置了,隱藏包含了,所以定義了專有名詞,隱式對象. 除了out和pageContext這兩個,其余7個都是servlet中已經有的,這裡主要介紹jsp獨有的out和pageContext. 2.out隱式對象 out隱式對象用於向客戶端發送文本數據。 out對象是通過調用pageContext對象的getOut方法返回的,其作用和用法與ServletResponse.getWriter方法返回的PrintWriter對象非常相似。 JSP頁面中的out隱式對象的類型為JspWriter,JspWriter相當於一種帶緩存功能的PrintWriter,設置JSP頁面的page指令的buffer屬性可以調整它的緩存大小,甚至關閉它的緩存。 只有向out對象中寫入了內容,且滿足如下任何一個條件時,out對象才去調用ServletResponse.getWriter方法,並通過該方法返回的PrintWriter對象將out對象的緩沖區中的內容真正寫入到Servlet引擎提供的緩沖區中: >>設置page指令的buffer屬性關閉了out對象的緩存功能 >>out對象的緩沖區已滿 >>整個JSP頁面結束 如下所示: <% out.write("11111"); response.getWriter().write("222222"); %> 結果: 為什麼會這樣? 上面明明先輸出的11..,但顯示時卻顯示為222..111? 主要是因為,首先Jspwriter會將數據先寫入緩沖區內,當jsp頁面結束時才會將緩沖區的內容顯示出來. 同時,整個jsp頁面中關於html頁面內容的部分也是通過jspwriter對象(即out的方式輸出),所以如下, 復制代碼 <body> 00000 <% //out.write("11111"); response.getWriter().write("222222"); %> </body> 復制代碼 會有如下輸出: 所以,jsp中盡量全部用out對象進行輸出,另外jsp頁面中盡量不要寫任何java代碼. 3.pageContext隱式對象 pageContext對象是JSP技術中最重要的一個對象,它代表JSP頁面的運行環境,這個對象不僅封裝了對其它8大隱式對象的引用,它自身還是一個域對象,可以用來保存數據。並且,這個對象還封裝了web開發中經常涉及到的一些常用操作,例如引入和跳轉其它資源、檢索其它域對象中的屬性等。 通過pageContext獲得其他對象 : getException方法返回exception隱式對象 getPage方法返回page隱式對象 getRequest方法返回request隱式對象 getResponse方法返回response隱式對象 getServletConfig方法返回config隱式對象 getServletContext方法返回application隱式對象 getSession方法返回session隱式對象 getOut方法返回out隱式對象 pageContext封裝其它8大內置對象的意義,這個主要用於自定義標簽. pageContext對象的方法: 復制代碼 public void setAttribute(java.lang.String name,java.lang.Object value) public java.lang.Object getAttribute(java.lang.String name) public void removeAttribute(java.lang.String name) pageContext對象中還封裝了訪問其它域的方法 public java.lang.Object getAttribute(java.lang.String name,int scope) public void setAttribute(java.lang.String name, java.lang.Object value,int scope) public void removeAttribute(java.lang.String name,int scope) 代表各個域的常量 PageContext.APPLICATION_SCOPE PageContext.SESSION_SCOPE PageContext.REQUEST_SCOPE PageContext.PAGE_SCOPE findAttribute方法 (*重點,查找各個域中的屬性) EL表達式 復制代碼 JavaWeb中有四個域對象,按作用范圍從小到大進行排序為pageContext(作用范圍為:page)--->request域(請求時)--->session(整個會話都有頝)--->application/servletContext(應用上下文都有頝) 例: 復制代碼 <body> <% request.setAttribute("data", "abc"); String data = pageContext.getAttribute("data",PageContext.REQUEST_SCOPE).toString(); out.write(data); out.write("<br>"); out.write(pageContext.findAttribute("data").toString());//依次從page request session application四個域中找對應的值 %> </body> 復制代碼 注:EL表達式中取值就是依靠pageContext.findAttribute()方法的. 三.JSP常用標簽 1.<jsp:include>標簽 <jsp:include>標簽用於把另外一個資源的輸出內容插入進當前JSP頁面的輸出內容之中,這種在JSP頁面執行時的引入方式稱之為動態引入。 語法: <jsp:include page="relativeURL | <%=expression%>" flush="true|false" /> page屬性用於指定被引入資源的相對路徑,它也可以通過執行一個表達式來獲得。 flush屬性指定在插入其他資源的輸出內容時,是否先將當前JSP頁面的已輸出的內容刷新到客戶端。 <jsp:include>標簽是動態引入, <jsp:include>標簽涉及到的2個JSP頁面會被翻譯成2個servlet,這2個servlet的內容在執行時進行合並。 而include指令是靜態引入,涉及到的2個JSP頁面會被翻譯成一個servlet,其內容是在源文件級別進行合並。 不管是<jsp:include>標簽,還是include指令,它們都會把兩個JSP頁面內容合並輸出,所以這兩個頁面不要出現重復的HTML全局架構標簽,否則輸出給客戶端的內容將會是一個格式混亂的HTML文檔。 2.<jsp:forward>標簽 <jsp:forward>標簽用於把請求轉發給另外一個資源。 語法: <jsp:forward page="relativeURL | <%=expression%>" /> page屬性用於指定請求轉發到的資源的相對路徑,它也可以通過執行一個表達式來獲得。 3.<jsp:param>標簽 當使用<jsp:include>和<jsp:forward>標簽引入或將請求轉發給其它資源時,可以使用<jsp:param>標簽向這個資源傳遞參數。 語法1: <jsp:include page="relativeURL | <%=expression%>"> <jsp:param name="parameterName" value="parameterValue|<%= expression %>" /> </jsp:include> 語法2: <jsp:forward page="relativeURL | <%=expression%>"> <jsp:param name="parameterName" value="parameterValue|<%= expression %>" /> </jsp:include> <jsp:param>標簽的name屬性用於指定參數名,value屬性用於指定參數值。在<jsp:include>和<jsp:forward>標簽中可以使用多個<jsp:param>標簽來傳遞多個參數。 例: home.jsp 復制代碼 <%@ 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>jsp tags</title> </head> <body> <%-- <jsp:include page="public/head.jsp"></jsp:include> --%> <jsp:forward page="/HomeServlet"> <jsp:param value="amosli" name="username"/> </jsp:forward> </body> </html> 復制代碼 web.xml: 復制代碼 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <welcome-file-list> <welcome-file>/home.jsp</welcome-file> </welcome-file-list> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>HomeServlet</servlet-name> <display-name>HomeServlet</display-name> <description></description> <servlet-class>com.amos.HomeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HomeServlet</servlet-name> <url-pattern>/HomeServlet</url-pattern> </servlet-mapping> <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error/error.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/500.jsp</location> </error-page> </web-app> 復制代碼 HomeServlet.java 復制代碼 package com.amos; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HomeServlet extends HttpServlet { private static final long serialVersionUID = 1L; public HomeServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); response.getWriter().write(username+",歡迎您!"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } } 復制代碼 流程:web.xml中配置歡迎界面為home.jsp,然後home.jsp轉向那個HomeServlet,然後將值顯示到網頁中. 效果如下圖所示: 或者將home.jsp頁面改為: 復制代碼 <body> <%-- <jsp:include page="public/head.jsp"></jsp:include> --%> <%String name="amosli"; %> <jsp:forward page="/HomeServlet"> <jsp:param value="<%= name %>" name="username"/> </jsp:forward> </body> 復制代碼 使用jsp語法表達式設置參數.