Servlet與JSP學習筆記(四) JSP核心(上)

前面的文章已經覆蓋了Servlet核心知識,因爲JSP與Servlet在很大程度上是相通的,所以關於JSP只須要介紹語法以及一些獨特的性質。
一樣能夠參考菜鳥筆記html

介紹JSP

首先,爲何要有JSP?

要回答這個問題,實際上只須要比較HTML、Servlet、JSP的優劣:java

  • HTML文件是靜態的,沒法返回動態結果。apache

  • Servlet能夠動態生成HTML頁面,可是在代碼裏寫HTML標記實在是不爽。session

  • 因而反過來,在傳統的HTML文件中加入Java程序片斷和JSP標記,就構成了JSP文件。app

JSP是怎麼工做的?

當容器接收到客戶端對JSP文件的請求時,會解析對應的JSP文件,把它翻譯成Servlet源文件,接着把Servlet源文件編譯成Servlet類,而後再初始化並運行Servlet。jsp

固然,一旦JSP文件已經被編譯過,下次運行時只須要找對應的Servlet類就好了。this

可見JSP和Servlet實際上是一回事,JSP只是一層外衣。其內容中不管是HTML標記仍是Java代碼,都大部分被編譯到了Servlet類的service()方法中。因而接下來就順便解釋了JSP的生命週期:spa

JSP的生命週期

  • 編譯階段:Servlet容器編譯servlet源文件,生成servlet類翻譯

  • 初始化階段:加載與JSP對應的servlet類,建立其實例,並調用它的初始化方法code

  • 執行階段:調用與JSP對應的servlet實例的服務方法

  • 銷燬階段:調用與JSP對應的servlet實例的銷燬方法,而後銷燬servlet實例

下圖給出了後面三個階段的示意:
JSP生命週期

其中:編譯出來的Servlet類繼承自javax.servlet.jsp.HttpJspPage接口,該接口繼承了javax.servlet.Servlet接口。jspInit()就對應Servlet的init(), jspDestroy()就對應Servlet的destroy(), _jspService()自沒必要說。

下面給出一個JSP文件和編譯出來的代碼,就一目瞭然了。

<!-- Hello.jsp -->
<html>
<head>
  <title>helloapp</title>
</head>
<body>
  <b>Hello,<%= request.getParameter("username") %></b>
</body>
</html>

編譯出的Servlet文件:

public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase {
  
  ...
  public void _jspInit() {
  }

  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;
    }

    // 能夠看出JSP的隱含對象是這麼來的。
    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("<head>\r\n");
      out.write("  <title>helloapp</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("  <b>Hello,");
      out.print( request.getParameter("username") );
      out.write("</b>\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);
    }
  }
}

JSP的語法

歸納地說,JSP文件中除了能夠直接包含HTML文本,還能夠包含如下內容:

  1. JSP指令(Directive)
    用來設置和整個JSP頁面相關的屬性。語法形式爲<%@ 指令 屬性1="值1" 屬性2="值2" %>。包括三種指令:

    • Page: 能夠指定language、content_type、errorPage、session等,還能夠用import屬性引入包。

    • Include: 包含其餘文件。

    • Taglib: 指定自定義標籤。

  2. JSP聲明

    聲明一個或多個變量、方法,供後面的Java代碼使用。聲明中的變量會被編譯成Servlet的(私有)成員變量。示例:

    <%! int i = 0; %> 
    <%! int a, b, c; %> 
    <%! Circle a = new Circle(2.0); %>
  3. Java程序片斷
    任何在"<%"和"%>"標記之間的Java代碼。默認會被編譯到Servlet類的service()方法中(若是用Page指定了method屬性,則會編到你指定的方法中)。若是你想複寫jspInit()jspDestroy()方法,應該在前面的JSP聲明中寫。

  4. Java表達式
    語法形式爲<%= JAVA表達式 %>。至關於被編譯成out.print(JAVA表達式)

  5. JSP隱含對象
    JSP隱含對象是JSP容器爲每一個頁面提供的Java對象,開發者能夠直接使用它們而不用顯式聲明。JSP隱含對象也被稱爲預約義變量。
    JSP所支持的九大隱含對象:

    對象 描述
    request HttpServletRequest類的實例
    response HttpServletResponse類的實例
    out PrintWriter類的實例,用於把結果輸出至網頁上
    session HttpSession類的實例
    application ServletContext類的實例,與應用上下文有關
    config ServletConfig類的實例
    pageContext PageContext類的實例,提供對JSP頁面全部對象以及命名空間的訪問
    page 相似於Java類中的this關鍵字
    Exception Exception類的對象,表明發生錯誤的JSP頁面中對應的異常對象

    看起來很犀利,但實際上從前面真實的Servlet代碼能夠看到,它們不過是在service()方法的最前面預先定義好的局部變量。

相關文章
相關標籤/搜索