Java Web(五) JSP詳解(四大作用域九大內建物件等)

一杯涼茶發表於2017-02-22

    前面講解了Servlet,瞭解了Servlet的繼承結構,生命週期等,並且在其中的ServletConfig和ServletContext物件有了一些比較詳細的瞭解,但是我們會發現在Servlet中編寫一些HTML程式碼,是很不方便的一件事情,每次都需要out.println(HTML); 因此就出現了JSP,來解決這樣的問題,JSP中的內容就是html,但是能夠巢狀java語言,現在來詳細瞭解一下JSP。

                                  --WH

一、JSP

    1、什麼是JSP?

       JSP(Java Server Pages):是以Java語言為基礎的動態網頁開發技術,

       特點:

          Servlet特點:在Java原始碼中嵌入html原始碼

          JSP特點:在html原始碼中嵌入java程式碼

       JSP就是Servlet

          1、tomcat獲得JSP檔案後,先將JSP轉成servlet,變成xxx.java(servlet原始碼),

            D:\java\tomcat7.0\apache-tomcat-7.0.53\apache-tomcat-7.0.53\work\Catalina\localhost\test01\org\apache\jsp

          |------------------------------------------------------------------------|   |---------|----------|-------|-----------------|

                tomcat安裝目錄                        引擎   主機  專案   固定包名  這個之下就是存放著jsp變成的servlet檔案.java和編譯檔案.class 

          2、tomcat將java檔案編譯成class檔案

             

          3、tomcat執行class檔案,並將結果輸出到瀏覽器,

 

       例項:

          建立一個jsp。檢視其轉換後的servlet程式碼。

          NewFile.jsp          

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>Insert title here</title>
 8 </head>
 9 <body>
10     hahaha
11 </body>
12 </html>
View Code

          NewFile_jsp.java          

 1 /*
 2  * Generated by the Jasper component of Apache Tomcat
 3  * Version: Apache Tomcat/7.0.53
 4  * Generated at: 2017-02-22 02:09:08 UTC
 5  * Note: The last modified time of this file was set to
 6  *       the last modified time of the source file after
 7  *       generation to assist with modification tracking.
 8  */
 9 package org.apache.jsp;
10 
11 import javax.servlet.*;
12 import javax.servlet.http.*;
13 import javax.servlet.jsp.*;
14 
15 public final class NewFile_jsp extends org.apache.jasper.runtime.HttpJspBase
16     implements org.apache.jasper.runtime.JspSourceDependent {
17 
18   private static final javax.servlet.jsp.JspFactory _jspxFactory =
19           javax.servlet.jsp.JspFactory.getDefaultFactory();
20 
21   private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
22 
23   private javax.el.ExpressionFactory _el_expressionfactory;
24   private org.apache.tomcat.InstanceManager _jsp_instancemanager;
25 
26   public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
27     return _jspx_dependants;
28   }
29 
30   public void _jspInit() {
31     _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
32     _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
33   }
34 
35   public void _jspDestroy() {
36   }
37 
38   public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
39         throws java.io.IOException, javax.servlet.ServletException {
40 
41     final javax.servlet.jsp.PageContext pageContext;
42     javax.servlet.http.HttpSession session = null;
43     final javax.servlet.ServletContext application;
44     final javax.servlet.ServletConfig config;
45     javax.servlet.jsp.JspWriter out = null;
46     final java.lang.Object page = this;
47     javax.servlet.jsp.JspWriter _jspx_out = null;
48     javax.servlet.jsp.PageContext _jspx_page_context = null;
49 
50 
51     try {
52       response.setContentType("text/html; charset=UTF-8");
53       pageContext = _jspxFactory.getPageContext(this, request, response,
54                   null, true, 8192, true);
55       _jspx_page_context = pageContext;
56       application = pageContext.getServletContext();
57       config = pageContext.getServletConfig();
58       session = pageContext.getSession();
59       out = pageContext.getOut();
60       _jspx_out = out;
61 
62       out.write("\r\n");
63       out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
64       out.write("<html>\r\n");
65       out.write("<head>\r\n");
66       out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
67       out.write("<title>Insert title here</title>\r\n");
68       out.write("</head>\r\n");
69       out.write("<body>\r\n");
70       out.write("\thahaha\r\n");
71       out.write("</body>\r\n");
72       out.write("</html>");
73     } catch (java.lang.Throwable t) {
74       if (!(t instanceof javax.servlet.jsp.SkipPageException)){
75         out = _jspx_out;
76         if (out != null && out.getBufferSize() != 0)
77           try { out.clearBuffer(); } catch (java.io.IOException e) {}
78         if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
79         else throw new ServletException(t);
80       }
81     } finally {
82       _jspxFactory.releasePageContext(_jspx_page_context);
83     }
84   }
85 }
View Code

            可以看到public final class NewFile_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent

            NewFile_jsp.java繼承自HttpJspBase。來看看HttpJspBase的原始碼

          HttpJspBase.java         

 1 /*
 2  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  * contributor license agreements.  See the NOTICE file distributed with
 4  * this work for additional information regarding copyright ownership.
 5  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  * (the "License"); you may not use this file except in compliance with
 7  * the License.  You may obtain a copy of the License at
 8  * 
 9  *      http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package org.apache.jasper.runtime;
19 
20 import java.io.IOException;
21 
22 import javax.servlet.ServletConfig;
23 import javax.servlet.ServletException;
24 import javax.servlet.http.HttpServlet;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27 import javax.servlet.jsp.HttpJspPage;
28 
29 import org.apache.jasper.compiler.Localizer;
30 
31 /**
32  * This is the super class of all JSP-generated servlets.
33  *
34  * @author Anil K. Vijendran
35  */
36 public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
37     
38     private static final long serialVersionUID = 1L;
39 
40     protected HttpJspBase() {
41     }
42 
43     @Override
44     public final void init(ServletConfig config) 
45         throws ServletException 
46     {
47         super.init(config);
48         jspInit();
49         _jspInit();
50     }
51     
52     @Override
53     public String getServletInfo() {
54         return Localizer.getMessage("jsp.engine.info");
55     }
56 
57     @Override
58     public final void destroy() {
59         jspDestroy();
60         _jspDestroy();
61     }
62 
63     /**
64      * Entry point into service.
65      */
66     @Override
67     public final void service(HttpServletRequest request, HttpServletResponse response) 
68         throws ServletException, IOException 
69     {
70         _jspService(request, response);
71     }
72     
73     @Override
74     public void jspInit() {
75     }
76 
77     public void _jspInit() {
78     }
79 
80     @Override
81     public void jspDestroy() {
82     }
83 
84     protected void _jspDestroy() {
85     }
86 
87     @Override
88     public abstract void _jspService(HttpServletRequest request, 
89                                      HttpServletResponse response) 
90         throws ServletException, IOException;
91 }
View Code

          public abstract class HttpJspBase extends HttpServlet implements HttpJspPage

            看到了一個熟悉的類,HttpServlet,我們編寫Servlet時就是繼承自該類,這裡也是繼承HttpServlet,並且HttpJspBase的原始碼會發現,生命週期也是有init()方法,service()方法,destory()方法,相當於_jspService()方法就是servlet的service()方法的執行,所以說JSP也是一個servlet。

        

          我們在JSP寫的所有html程式碼,都會被轉換為servlet中的out.write(html)程式碼來輸出。看圖

              

 

 

       小總結:

              

           對於jsp轉換成的servlet原始碼,之後我們會在進行詳細分析,現在只需要知道jsp中的內容在servlet中被轉換成什麼了,在哪裡被轉換了即可。其中_jspService()方法的詳細內容下面會講解

           注意:jsp 生成java原始碼,預設第一次生成,之後直接執行,除非內容修改,具體點說,由於JSP只會在客戶端第一次請求的時候被編譯,因此第一次請求JSP時會感覺比較慢,而之後的請求因為不會編譯JSP,所以速度就快多了,如果將Tomcat儲存的JSP編譯後的class檔案刪除,Tomcat也會重新編譯JSP。在開發Web程式的時候經常需要修改JSP,Tomcat能夠自動檢測到JSP程式的改動,如果檢測到JSP原始碼發生了改動,Tomcat會在下次客戶端請求JSP時重新編譯JSP,而不需要重啟Tomcat,這種自動檢測功能預設是開啟的,檢測改動會消耗少量的時間,在部署web應用程式的時候可以在web.xml中將它關掉。這也就是為什麼我們能夠在jsp頁面直接修改內容,而不用重新啟動伺服器的原因。

           因為JSP就是servlet,那麼生命週期也就是跟serlvet一樣。

           JSP和servlet有一點區別就在於:jsp是先部署後編譯,而servlet是先編譯後部署。

 

二、JSP語法

     JSP模版資料:

        就是JSP中的HTML程式碼,它的內容給是固定的,無論程式如何執行模版資料輸出到客戶端瀏覽器時都不會發生改變,當我們建立一個JSP時,模版就已經固定了。

     元素:JSP中的java部分,包括指令碼(JavaScript,或者java程式碼)以及JSP指令(Directive)與JSP標籤(Tag)等,元素決定著程式的流程,元素是不會顯示到瀏覽器的。這幾個都會在接下來講解到

     JSP指令碼:

        1、使用<% 編寫java程式碼 %>,中間java程式碼必須遵循Java語法

            

           為什麼能夠使用out輸出?這裡就涉及到了JSP的九大內建物件了,後面會講解到,到時候回過頭來在看看這裡,就會知道為什麼可以使用。

           來看看,jsp變為servlet時的程式碼是如何編寫的。

            

          在JSP中JSP指令(後面會講):

                <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

                  這句程式碼在servlet就變為了

                response.setContentType("text/html; charset=UTF-8");//這句程式碼的意思就是通知tomcat和瀏覽器都使用UTF-8碼錶,並且傳送回瀏覽器的資料型別是text/html。這是有JSP指令中畫紅色部分程式碼轉變的,而指令中的pageEncoding="UTF-8"的意思是JSP轉換為Servlet時採用UTF-8碼錶編碼,因為可能JSP中包含中文。

          對於JSP模版資料來說,就原封不動的使用out.write()來輸出到瀏覽器

          而對於JSP元素來說,就會變成普通的java程式碼,因為在servlet中,就可以直接編寫java程式碼。

                        

       2、使用<%=xxx %>來輸出結果

            

          使用<%=result %>來輸出結果,servlet中就會將其轉換為out.print(result)進行輸出。輸出各種型別資料:int、double、boolean、String、Object等

              

       3、JSP註釋

          <%-- --%>  :jsp註釋,

          //  :java單行註釋

          /*  */  :Java多行註釋

          <!-- -->   :這個註釋,會傳送到瀏覽器端的原始碼中顯示

          註釋分別在servlet中如何顯示的?

              

            

              

          JSP註釋不會在servlet檔案中顯示,而java註釋則會,但其所有的註釋到了瀏覽器端,都不會出現在原始碼中,只有<!-- -->這個註釋會到瀏覽器的網頁原始碼中去

 

      4、JSP中申明方法與屬性(全域性變數)  使用<%!  方法、屬性%>

          這個就不演示了,就是在JSP中編寫方法或者屬性時,使用<%! %>括起來。

              

       5、在JSP中使用if語句,或者使用for迴圈,whilt迴圈等都可以實現,也就是編寫指令碼而已。     

 

三、JSP指令

     指令用來申明JSP頁面的一些屬性,比如編碼方式,文件型別。我們在servlet中也會申明我們使用的編碼方式和響應的文件型別的,而JSP就是用指令來申明。上面我們也說到了一條指令,也就是page指令,

        JSP指令格式:<%@ directive {attribute=value}* %>

           解釋:

              directive:指令名稱,例如page指令

              attribute=value:緊跟指令名稱後面的就是各種屬性,以鍵值對的形式書寫

              *:代表後面能跟0個或多個屬性。

        例如: page指令:用來宣告JSP頁面的屬性等。

           <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  page指令,後面跟著三個屬性,分別是language、contentType、pageEncoding。這只是其中的幾個屬性,並沒有寫全,page指令允許的屬性如下表所示

        屬性名稱        取值範圍          描述

        language        java      解釋該JSP檔案時採用的語言,一般為java語言,預設為java

        extends        任何類的全名   編譯該JSP檔案時繼承哪個類,JSP為Servlet,因此當指明繼承普通類時需要實現Servlet的init、destroy等方法

        import         任何包名、類名  引入該JSP中用到的類、包等,import是唯一可以宣告多次的page指令屬性,一個import可以引用uogelei,中間用英文逗號隔開,

                              如<%@ page import="java.util.List,java.util.ArrayList"%>

        session        true、false    該JSP內是否內建Session物件,如果為true,則內建Session物件,可直接使用,否則反之,預設為true

        autoFlush       true,false    是否執行快取,如果為true,則使用out.println()等方法輸出的字串並不是立刻到達客戶端伺服器的,而是暫時存到快取裡,快取滿

                             了或者程式執行完畢或者執行out.flush()操作時才到客戶端,預設為true。

        buffer        none或者數字KB   指定快取大小,當autoFlush設為true時有效,例如<%@ page buffer=10kb%>

        isThreadSafe      true,false    是否執行緒安全,如果為true,則執行多個執行緒同時執行該jsp程式,否則只執行一個執行緒,其餘執行緒等待,預設為false

        isErrorPage      true,false     指定該頁面是否為錯誤顯示頁面,如果為true,則該JSP內建有一個Exception物件exception,可直接使用,否則沒有,預設為false

        errorPage     某個JSP頁面的相對路徑  指明一個錯誤頁面,如果該JSP程式丟擲一個未捕捉的異常,則轉到errorPage指定的頁面,errorPage指定的頁面通常

                               isErrorPage屬性為true,且內建的exception物件為未捕捉的異常

        contentType     有效的文件型別    客戶端瀏覽器根據該屬性判斷文件型別,例如 HTML格式為text/html、純文字格式為text/plain、JPG影象為image/jpeg、GIF圖                              像為image/gif、WORD文件為application/msword,該屬性常跟著charset設定編碼一起,作用是通知伺服器和瀏覽器都使用同一                              個碼錶

        info          任意字串      指明JSP的資訊,該資訊可以通過Servlet.getServletInfo()方法獲取到

    trimDirective Whitespaces    true、false     是否去掉指令前後的空白字元,預設為false

        pageEncoding    UTF-8,ISO-8859-1等    指定一張碼錶來對該JSP頁面進行編碼,

        

      include指令

          比較簡單,只有一種形式 <%@ include file="relativeURL"%>  relativeURL:本應用程式內另一個JSP檔案或者HTML檔案的路徑,例如,網址內所有頁面均有一個統一風格的導航欄和頁尾版權,那麼就可以使用該指令將其包含進來,  

          特點:include指令會將包含頁面的原始碼新增到使用include指令的頁面中來,然後編譯成class檔案,而等下會講到的一個JSP行為,<jsp:include page="relativeURL">作用跟include指令一樣,但是不同的是,include行為是執行時單獨執行包含頁面,然後把執行的結果包含到本頁面來,屬於先執行後包含。

      taglib指令

          JSP支援標籤技術,後面會講到標籤的用法,jstl標籤庫的使用等,

          作用:用來指明JSP頁面內使用的JSP標籤庫,taglib指令有兩個屬性,uri為類庫的地址,prefix為標籤的字首

          <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

       

四、JSP行為

     前面講了JSP語法,介紹了JSP頁面中的內容有哪些,分別有什麼作用,就兩個東西,模組資料和元素。其中元素有包括指令碼指令標籤,指令碼就是JSP中嵌入java程式碼,指令作用就是申明頁面的屬性,那標籤是幹嘛的,標籤分為JSP自帶內建的標籤,和通過taglib指令來使用JSP標籤庫,或者自定義標籤。現在我們先來講一些JSP內建的標籤。

     JSP內建的標籤就被稱為JSP行為(JSP Actions)。只要書寫很少的標記程式碼就能使用JSP提供的豐富功能,JSP行為其實是對常用的JSP功能的抽象與封裝,可以取代jsp指令碼,讓JSP中就少一些嵌入java程式碼的地方。

      格式:<jsp:elements {attribute="value"}* />  

          jsp:標籤的字首,說明是jsp內建的標籤,

          elements:行為的名稱,

          attribute=value:使用鍵值對來編寫屬性

          *:能指定0個或多個屬性對

    <jsp:include />行為

       include行為用於執行時包含某個檔案,如果被包含的檔案為JSP程式,則先會執行JSP程式,然後在把執行的結果包含進來。 作用是跟include指令一樣的,唯一的區別就在於,include指令是將被包含的檔案的原始碼加入到了本JSP程式中,然後在進行編譯,屬於靜態包含,而include行為只是將被包含的檔案的執行結果包含進自己。屬於動態包含

          

    Java bean行為

       是一組與Java Bean 相關的行為,包括useBean行為、setProperty行為、getProperty行為等

       Java Bean就是普通的Java類,也被稱為POJO,只有私有的屬性與對應的getter方法和setter方法,注意其中當私有的屬性為boolean型別時,習慣上一般把getter方法寫成isXxx();而不是getXxx();

       useBean行為  

          <jsp:useBean id="beanObject" class="className" scope="Value">  作用:在jsp中定義一個java bean物件,   

             id:指明Java Bean物件的名稱,JSP中可以使用該名稱引用該Java Bean物件,相當於給new出來的物件取一個變數名,

             class:Java Bean類的全名

             scope:該java bean物件的作用範圍,可以寫的就四個,也就是JSP的四大作用域,page、request、session、application

                  page:只能在當前JSP頁面使用,如果不在JSP頁面,那麼就會失效

                  request:這個前面學過,A頁面請求轉發到B頁面,那麼使用的是同一個request,那麼A,B頁面都算是request的作用域,也就是通過請求轉發的頁面都是其作                       用域

                  session:該作用域在一個web專案下任何位置應該讀訪問的到,只要cookie不關閉,並且cookie設定  的訪問路徑為"/",

                  application:其實就是Servlet中的servletContext,伺服器下的所有專案都能訪問到。

       setProperty行為

          <jsp:setProperty name="beanName" property="propertyName" value="">

            對Java Bean物件進行屬性的設定

            name:java bean物件的名稱,也就是在useBean行為中的id

            property:物件中的屬性名,

            value:要對其屬性進行賦值的值

              

       getProperty行為

          <jsp:getProperty name="beanName" property="propertyName" />

            獲取JavaBean物件的某個屬性值

            name:java bean 物件的名稱,也就是在useBean行為中的id

            property:物件的屬性名

      例子:  javabean:User.java  NewFile.jsp

      User.java

 1 package a;
 2 
 3 public class User {
 4     private int id;
 5     private String username;
 6     private String password;
 7     public int getId() {
 8         return id;
 9     }
10     public void setId(int id) {
11         this.id = id;
12     }
13     public String getUsername() {
14         return username;
15     }
16     public void setUsername(String username) {
17         this.username = username;
18     }
19     public String getPassword() {
20         return password;
21     }
22     public void setPassword(String password) {
23         this.password = password;
24     }
25     
26     
27 }
View Code

      NewFile.jsp

1 <body>
2     <!-- 建立一個新的javabean物件user,會先判斷在page作用域內是否有叫user物件的javabean,如果有則取它,如果沒有則建立新的javabean物件  -->
3     <jsp:useBean id="user" class="a.User" scope="page"></jsp:useBean>
4     <!-- 對javabean物件的username進行賦值 -->
5     <jsp:setProperty property="username" name="user" value="wu"/>
6     <!-- 獲取javabean物件的username屬性 -->
7     <jsp:getProperty property="username" name="user"/>
8 </body>
View Code

      可以檢視NewFile.jsp變為servlet後的原始碼,看看我們寫的javabean行為會被轉換為何種語句

          

      這裡出現了一個JSP九大內建物件中的一個,pageContext。現在簡單提一句,pageContext就是JSP頁面的管理者(上下文),其中的getAttribute(name,scope)方法是獲取指定作用域中的資料的,如果getAttribute(name)方法的話,預設是對page作用域進行操作,findAttribute(name)依次從page、request、session、application獲得內容。 

      在第一個紅框中,就代表中我們的useBean行為,其中進行了一次判斷,就是如果在page作用域中找不到user這個物件,那麼就建立一個新的,否則就使用找到的這個user物件,

      第二個紅框中,代表著我們的setProperty行為,先找到user物件,然後在對其屬性進行賦值

      第三個紅框中,代表著我們的getProperty行為,也是先找到user物件,然後在獲取其屬性的值。

 

      注意:對於javabean行為來說,有一個特點的地方,就是當請求過來的引數對應javabean的屬性時,可以為其一次性設定所有的值

          <jsp:setProperty name="user" property="*" /> //設定user的所有屬性,屬性值從request中自動取得,*代表所有屬性。

        

    <jsp:forward />行為

      實現請求轉發功能,Servlet中通過request.getRequestDispatcher("someServlet").forward(request,response);而在JSP中也能夠實現相同的功能,只不過用的是<jsp:forward />行為,實際上forward行為就是對其進行了封裝。

      格式:

        <jsp:forward page="someServlet">

           <jsp:param name="param1" value="value1"/>

           <jsp:param name="param2" value="value2"/>

        </jsp:forward>

        page:需要跳轉到的頁面或者servlet、 <jsp:param/>引數行為,帶一些引數過去,name、value是以鍵值對的形式帶過去的

      例如:

         NewFile.jsp

               

         MyServlet.java

           

         訪問:http://localhost:8080/test01/NewFile.jsp

           

          瀏覽器位址列沒有改變,說明是請求轉發

         NewFile_jsp.java

          

          使用return的好處是執行完上面的轉發,就直接return,沒有必要在執行下面的程式碼了,對引數使用了URLEncode進行編碼,說明該<jsp:param/>可以直接傳遞中文,但是前提是要設定request.setCharacterEncoding("UTF-8");為什麼這樣做,看上面框起來中的程式碼。

 

    <jsp:directive/>行為

       directive行為,就相當於JSP指令,比如<jsp:directive.page/>相當於<%@ page %>指令,等等其它指令是一樣的書寫格式。        

 

五、JSP隱藏的九大內建物件和四大作用域

     之前那麼一大段內容,就是為了講解什麼是JSP,JSP中的內容是怎麼樣的,到這裡應該知道的差不多了, 但我們還要深入瞭解一些東西,我們知道JSP中的內容就只有兩種,模版資料,和元素,元素就包括了指令呀,指令碼呀,標籤(行為)呀,指令碼會慢慢被標籤全部代替,也就是說JSP中基本上不會嵌入Java程式碼,但是我們也知道JSP會轉換為servlet,在Servlet中,輸出資料時,都需要通過response.getWrite();但是在JSP中,直接使用out物件進行輸出,為什麼呢?這就是因為out為JSP的一個隱藏物件,JSP中內建了9個隱藏物件,使得JSP比Servlet使用起來更簡單,更方便,

    page、config、application、request、response、session、out、exception、pageContext

      page:page物件代表當前JSP頁面,是當前JSP編譯後的Servlet類的物件。相當於this。

      config:標識Servlet配置,型別:ServletConfig,api跟Servlet中的ServletConfig物件是一樣的,能獲取該servlet的一些配置資訊,能夠獲取ServletContext

      application:標識web應用上下文,型別:ServletContext,詳情就看Servlet中的ServletContext的使用

      request:請求物件,  型別:httpServletRequest

      response:響應物件  型別:httpServletResponse

      session:表示一次會話,在伺服器端記錄使用者狀資訊的技術

      out:輸出響應體 型別:JspWriter

      exception 表示發生異常物件,型別 Throwable,在上面我們介紹page指令中的一個errorPage屬性時就有說到他

      pageContext:表示 jsp頁面上下文(jsp管理者) 型別:PageContext

     標記了紅色的物件就是JSP獨有的,其他的都是Servlet中的老東西。

      

      在這個由jsp轉換為servlet的檔案中,只能看到8個內建物件,少了exception物件,因為我們在將page指令時,說過一個isErrorPage屬性,預設是false,被關閉了,所以其中並沒有exception物件。

     JSP的四大作用域:page、request、session、application

        這四大作用域,其實就是其九大內建物件中的四個,為什麼說他們也是JSP的四大作用域呢?因為這四個物件都能儲存資料,比如request.setAttribute()注意和request.setParameter()區分開來,一個是儲存在域中的、一個是請求引數,session.setAttribute()、application其實就是SerlvetContext,自然也有setAttribute()方法。而page作用域的操作就需要依靠pageContext物件來進行了。在上面我們也有提到JSP的四大作用域,

        page作用域:代表變數只能在當前頁面上生效

        request:代表變數能在一次請求中生效,一次請求可能包含一個頁面,也可能包含多個頁面,比如頁面A請求轉發到頁面B

        session:代表變數能在一次會話中生效,基本上就是能在web專案下都有效,session的使用也跟cookie有很大的關係。一般來說,只要瀏覽器不關閉,cookie就會一直生效,cookie生效,session的使用就不會受到影響。

        application:代表變數能一個應用下(多個會話),在伺服器下的多個專案之間都能夠使用。比如baidu、wenku等共享帳號。

     out物件:

        型別:JspWriter

        jsp 輸出底層使用 response.getWriter();什麼意思呢?這裡就要講解一下JSP快取和Servlet快取了,輸出的過程是這樣的

                 

        JSP頁面轉換為Servlet後,使用的out物件是JspWriter型別的,所以是會先將要傳送的資料存入JSP輸出快取中,然後,等JSP輸出快取滿了在自動重新整理到servlet輸出快取,等serlvet輸出快取滿了,或者程式結束了,就會將其輸出到瀏覽器上。除非手動out.flush()。

        驗證servlet輸出快取和JSP輸出快取和我們上面所說的是正確的。

            

             

          分析:如果按沒有jsp快取和servlet快取的話,輸出的結果應該是aaaabbbbcccc,但是輸出的卻是bbbbaaaacccc,為什麼呢?按照我們上面所說的原理進行分析,out物件是先將其輸出到JSP快取中,所以aaaa加入了jsp快取,而response.getWriter().print("bbbb")是直接將bbbb輸出到servlet快取中,然後又使用out物件將cccc輸出到jsp快取,到程式結束,servlet快取中有bbbb,然後jsp會將快取中的內容就重新整理到servlet快取中,serlvet就是bbbbaaaacccc了,然後到瀏覽器也就得到我們的輸出結果了。如果在12行將註釋去掉,那麼輸出的結果又會是什麼呢?答案就是aaaabbbbcccc,過程自行分析。

            

 

     pageContext物件:重點

        這個功能就比較強大了,比較牛逼,基本上什麼他都有,因為是它是JSP頁面的管理者(上下文),所以JSP中的內建物件呀,它統統能夠獲得,下面介紹它的api。

        1、獲得其它八大內建物件 getXxx()

          pageContext.getOut();  //獲得out物件

          pageContext.getApplication();  //獲得application物件

          等等....

        2、對作用域的屬性進行操作(四大作用域)

          對預設作用域的屬性進行操作。page

          pageContext.getAttribute(name);  //獲得page作用域資料

          pageContext.setAttribute(name,value);  //給page作用域設定內容

          pageContext.removeAttribute(name);  //給page作用域移除內容

        3、對指定作用域的屬性進行操作

          getAttribute(name,scope);  //獲得 指定作用域中的資料

          setAttribute(name,value);  //給指定作用域設定內容

          removeAttribute(name ,scope)  移除指定作用域的內容(page/request/session/application)

        4、提供作用域常量

          PageContext.PAGE_SCOPE  page

          PageContext.REQUEST_SCOPE  request      

          PageContext.SESSION_SCOPE  response

          PageContext.APPLICATION_SCOPE  application

        5、一次獲得指定名稱內容

          findAttribute(name);  //依次從page、request、session、application 獲得內容

 

     response物件:

        就是響應物件,、如果不瞭解就看看講解request和response的這一章節的內容

 

     config物件:

        型別:ServletConfig

        能夠獲取servlet的初始化引數,獲取servletContext物件,獲取servletName

        api詳情請看講解servlet這一章節

 

     exception異常物件:

        包含了異常的資訊

        使用它,必須結合page指令中的isErrorPage屬性和errorPage屬性。

        exception.jsp  拋異常的一個NullPointException,並且跳轉到error.jsp錯誤顯示頁面  errorPage屬性的意思是如果發生未捕捉到的異常,將會跳轉到error.jsp頁面

            

        error.jsp  isErrorPage屬性說明該頁面是一個錯誤顯示頁面,則可以使用exception物件

            

        訪問http://localhost:8080/test01/exception.jsp

            

六、總結

    通過上面一大堆一大堆的學習,我們應該知道這些東西

    1、什麼是JSP?

      JSP本質上就是一個servlet,因為servlet輸出html太麻煩了,所以就有了JSP,JSP就是專門用來書寫html的,當然其中也能寫java程式碼。

    2、JSP的內容包括什麼?

      模版資料和元素。其中元素有包括指令碼(java程式碼)、指令(頁面屬性)、和行為(標籤,為了JSP中不嵌入那麼多java程式碼衍生的)

    3、JSP中九大內建物件是哪九個?

      九大內建物件,page、config、appliction、request、response、session、out、exception、pageContext

    4、九大內建物件和servlet中物件的關係

      page就是jsp轉換為servletservlet物件本身,也就是this

      config -- Servlet中的servletConfig

      application -- Servlet中的ServletContext

      request  -- Servlet中的request

      response  -- Servlet中的response

      session  -- Servlet中的session    

      out  -- JspWriter

      exception  -- 異常物件

      pageContext  -- 表示 jsp頁面上下文(jsp管理者) 型別:PageContext,

        其中pageContext物件最牛逼,有了他就擁有了天下,哈哈~

   5、JSP中的四大作用域。

      page、request、session、application

      其中操作page域中屬性需要藉助pageContext物件。

   6、JSP中還有其他兩大塊內容

      一個是EL表示式,很重要,

      另一個是jstl標籤庫的使用,也很重要,在接下來的兩節中,就會講解到。敬請期待。

 

相關文章