1. 程式人生 > >JavaWeb中的九大內建物件概述

JavaWeb中的九大內建物件概述

本身想把九個內建物件放到Listener裡面寫,但是這樣寫的話再看起來比較麻煩,還是單獨拿出來做一篇文章吧。

JSP內建物件:何為內建?就是不用我們建立,JSP它本身裡面就有這些物件。

有人會問,內建物件是在那個過程被建立的?是怎麼被建立的?拿著這個問題,我查了些資料,進行總結,口說無憑,眼見為實:

首先,我在web工程裡面新增一個nzdx.jsp頁面:


然後我用SearchEverything去搜索,nzdx_jsp.java和nzdx_jsp.class檔案,發現沒有這兩個檔案,如圖:


注:SearchEverything能夠快速在本地搜尋指定名稱的檔案,這個軟體挺好用的。

然後,我啟動tomcat,並用瀏覽器訪問該頁面,且用SearchEverything搜尋jsp轉換成java和class的檔案,得到下圖:


我們發現,我們的jsp頁面轉換成了java檔案和class檔案,這個過程是怎麼進行的呢?下面上個圖,來解釋該過程(圖是盜的,對不起原作者,嘿嘿)


接下來看一下,生成的java檔案,瞭解一下其中內容:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/8.0.15
 * Generated at: 2017-07-19 02:26:31 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class nzdx_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.lang.Object page = this;
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("<html>\r\n");
      out.write("<body>\r\n");
      out.write("<h2>å置对象</h2>\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

程式碼中可以看到web容器(tomcat)幫我們將JSP轉換成Servlet,再將Servlet轉換成java檔案。

轉換成的java檔案中存在init、Destory、Service這三個方法,你是否想起來我們學習Servlet裡面的方法呢,這三個方法是不是和那三個方法相同?

你猜的沒錯,就是相同的。

接下來我們再看內建物件,下面紅色標記的程式碼就是從上面生成的程式碼中擷取的,我們所要知道的內建物件就是在這個時候被宣告的,他們是9個內建物件中的6個:

pageContext,session,application,config,out,page(紅色程式碼塊) 

final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;

在上述程式碼中可以看到,接下來的try語句塊裡面對其進行了賦值(藍色程式碼塊)

pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
final java.lang.Object page = this;

這時候你會奇怪,剩下的三個呢?

剩下的三個分別是HttpServletRequest和HttpServletResponse,ServletException,其中2個是final宣告的形參,1個是thorw後的程式碼(紫色程式碼塊)

final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException

熟悉的request和response回來了,我們知道他們分別屬於HttpServletRequest類和HttpServletResponse類,知道Httpservlet這個類的,就知道這兩個內建物件那裡來的,不明白的請學習Servlet。

而exception這個物件,我們必須將jsp檔案的page中指定isErrorPage為true時,才可以使用。

什麼意思?意味著在JSP頁面指定這個屬性為true後,該jsp頁面在轉換成java檔案時才會自動為我們定義exception這個物件,大家可以自定義個jsp檔案,將其errorPage指定為true,再找到對應的java檔案,便可以發現exception這個物件了。

還是老話,耳聽為虛,眼見為實:


再看生成的java檔案,我將其和之前生成的nzdx_jsp.java進行對比:


我們發現,多出來了一個exception物件,至此,所有的內建物件的建立和複製我們都大概瞭解了一遍,每個物件的具體功能和詳細描述如下,這些內容網上千篇一律,我就隨便找了一篇copy了一下。

注意:通常所說的ServletContext其實和Jsp頁面中引用的application是一回事,只是一個用於JSP頁面,一個用於java檔案。

1、request物件

     request 物件是 javax.servlet.httpServletRequest型別的物件。 

該物件代表了客戶端的請求資訊,主要用於接受通過HTTP協議傳送到伺服器的資料。(包括頭資訊、系統資訊、請求方式以及請求引數等)。

     request物件的作用域為一次請求。

2、response物件

response 代表的是對客戶端的響應,主要是將JSP容器處理過的物件傳回到客戶端。

response物件也具有作用域,只在JSP頁面內有效。

3、session物件

session 物件是由伺服器自動建立的與使用者請求相關的物件。伺服器為每個使用者都生成一個session物件,用於儲存該使用者的資訊,跟蹤使用者的操作狀態。

session物件內部使用Map類來儲存資料,因此儲存資料的格式為 “Key/value”。 session物件的value可以使複雜的物件型別,而不僅僅侷限於字串型別。

4、application物件

application 物件可將資訊儲存在伺服器中,直到伺服器關閉,否則application物件中儲存的資訊會在整個應用中都有效。

與session物件相比,application物件生命週期更長,類似於系統的“全域性變數”。

5、out 物件

out 物件用於在Web瀏覽器內輸出資訊,並且管理應用伺服器上的輸出緩衝區。

在使用 out 物件輸出資料時,可以對資料緩衝區進行操作,及時清除緩衝區中的殘餘資料,為其他的輸出讓出緩衝空間。

待資料輸出完畢後,要及時關閉輸出流。

6、pageContext 物件

pageContext 物件的作用是取得任何範圍的引數,可以獲取 JSP頁面的out、request、reponse、session、application 等物件。

pageContext物件的建立和初始化都是由容器來完成的,在JSP頁面中可以直接使用 pageContext物件。

7、config 物件

config 物件的主要作用是取得伺服器的配置資訊。通過 pageConext物件的 getServletConfig() 方法可以獲取一個config物件。

當一個Servlet 初始化時,容器把某些資訊通過 config物件傳遞給這個 Servlet。 

開發者可以在web.xml 檔案中為應用程式環境中的Servlet程式和JSP頁面提供初始化引數。

 page 物件代表JSP本身,只有在JSP頁面內才是合法的。 page隱含物件本質上包含當前 Servlet介面引用的變數,類似於Java程式設計中的 this 指標。

9、exception 物件

 exception 物件的作用是顯示異常資訊,只有在包含 isErrorPage="true" 的頁面中才可以被使用,在一般的JSP頁面中使用該物件將無法編譯JSP檔案。

     excepation物件和Java的所有物件一樣,都具有系統提供的繼承結構。exception 物件幾乎定義了所有異常情況。

在Java程式中,可以使用try/catch關鍵字來處理異常情況;

在JSP頁面中出現沒有捕獲到的異常,就會生成 exception 物件,並把 exception 物件傳送到在page指令中設定的錯誤頁面中,然後在錯誤頁面中處理相應的 exception 物件。