WEB_02_JSP/Servlet及相關技術詳解

1 Web應用和web.xml文件

1.1 構建Web應用

myProject
|-WEB-INF
|   |-classes
|   |-lib
|   |-web.xml
|-a.html

1.2 配置描述符web.xml

提示:
1.對於Servlet3.0規範而言,WEB-INF路徑下的web.xml文件不在是必須的,但通常還是建議保留該文件。
2.對於Java Web應用而言,WEB-INF是一個特殊的文件夾,Web容器會包含該文件夾下的內容,客戶端瀏覽器無法訪問WEB-INF路徑下的任何內容。

例1:在web.xml文件中配置首頁
在web.xml文件中配置首頁使用welcome-file-list元素,該元素能包含多個welcome-file子元素,其中每個子元素配置一個首頁。

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

當Web應用中包含index.html頁面時,如果瀏覽器直接訪問該Web應用,系統將會把該頁面呈現給瀏覽者;當index.html頁面不存在時,則由index.htm頁面充當首頁,以此類推。

2 JSP的基本原理

2.1 JSP頁面的內容由如下兩部分組成。

靜態部分:標準的HTML標籤,靜態的頁面內容,這些內容與靜態的HTML頁面相同。
動態部分:受Java程序控制的內容,這些內容由Java程序來動態生成。

2.2 簡單的JSP頁面

<body>
    現在的時間是:<br>
    <%out.println(new java.util.Date()); %>
</body>

這裏寫圖片描述

2.3 JSP的本質依然是Servlet(一個特殊的java類)

1.每個JSP頁面就是一個Servlet實例--JSP頁面由Servlet容器編譯成Servlet,Servlet再負責響應用戶請求。對於Tomcat而言,JSP頁面生成的Servlet放在work路徑對應的Web應用下。
2.JSP頁面裏的Java代碼不僅僅可以輸出動態內容,還可以動態控制頁面裏的靜態內容。
3.JSP頁面中的所有內容都是由對應Servlet文件的頁面輸出流來完成。

例1:簡單的JSP頁面

 <body>
    <%for(int i = 0;i<7;i++){
        out.println("<font size='"+i+"'>");
        %>
        學習java web和SSH框架</font><br>
    <% } %>
</body>

例2:Tomcat容器將上面程序編譯成Servlet

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.52
 * Generated at: 2017-09-04 01:41:39 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.*;
import java.util.*;

public final class index3_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 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;charset=UTF-8");
      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('\r');
      out.write('\n');

String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

      out.write("\r\n");
      out.write("\r\n");
      out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
      out.write("<html>\r\n");
      out.write("  <head>\r\n");
      out.write("    <base href=\"");
      out.print(basePath);
      out.write("\">\r\n");
      out.write("    \r\n");
      out.write("    <title>歡迎</title>\r\n");
      out.write("\t<meta http-equiv=\"pragma\" content=\"no-cache\">\r\n");
      out.write("\t<meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n");
      out.write("\t<meta http-equiv=\"expires\" content=\"0\">    \r\n");
      out.write("\t<meta http-equiv=\"keywords\" content=\"keyword1,keyword2,keyword3\">\r\n");
      out.write("\t<meta http-equiv=\"description\" content=\"This is my page\">\r\n");
      out.write("\t<!--\r\n");
      out.write("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\r\n");
      out.write("\t-->\r\n");
      out.write("  </head>\r\n");
      out.write("  \t\r\n");
      out.write("  <body>\r\n");
      out.write("   \t");
for(int i = 0;i<7;i++){
        out.println("<font size='"+i+"'>");

      out.write("\r\n");
      out.write("   \t\t學習java web和SSH框架</font><br>\r\n");
      out.write("   \t");
 } 
      out.write("\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 { 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);
    }
  }
}

該Java類主要包含如下3個方法:(去除方法名中的_jsp前綴,再將首字母小寫)
init():初始化JSP/Servlet的方法
destory():銷燬JSP/Servlet之前的方法
service():對用戶請求生成響應的方法

這裏寫圖片描述

2.4 結論:

1.JSP文件必須在JSP服務器內運行
2.JSP文件必鬚生成Servlet才能執行
3.每個JSP頁面的第一個訪問者速度很慢,因爲必須等待JSP編譯成Servlet。
4.JSP頁面的訪問之無需安裝任何客戶端,甚至不需要可以運行Java的運行環境,因爲JSP頁面輸送到客戶端的是標準的HTML頁面。

3 JSP註釋

jsp註釋用於標註在程序開發過程中的開發提示,不會輸出到客戶端

3.1 與HTML註釋的區別

JSP註釋格式:
<%--註釋內容 --%>
HTML註釋格式:
<!-- HTML註釋內容 -->

例1:頁面源碼展示:

<body>
    <%--註釋內容 --%>
    <%--江山如此多嬌 --%>
    <!-- HTML註釋內容 -->
    <!-- 引無數英雄競折腰 -->
</body>



<body>


    <!-- HTML註釋內容 -->
    <!-- 引無數英雄競折腰 -->
 </body>
結論:HTML的註釋可以通過源代碼查看到,但是JSP的註釋是無法通過源代碼查看的,進一步說明JSP註釋不會被髮送到客戶端。

4 JSP聲明

JSP聲明用於聲明變量和方法。在聲明方法的時候似乎是不需要定義類就可以直接定義方法,方法似乎可以脫離類單獨存在。實際上,JSP聲明將會被準換成對應Servlet的成員變量或成員方法,仍然如何Java語法。

4.1 格式:

<%! 聲明部分 %>

例1:使用JSP聲明的示例頁面

</head>
    <%!
        //聲明一個整形變量
        private int count;
        //聲明一個方法
        public String info(){
            return "hello";
        }
    %>
  <body>
    <%
        //將count的值輸出後加1
        out.println(count++);
    %>
    <br>
    <%
        //輸出info方法的返回值
        out.println(info());
    %>
  </body>

這裏寫圖片描述

例2:對應Servlet代碼:

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


        //聲明一個整形變量
        private int count;
        //聲明一個方法
        public String info(){
            return "hello";
        }
    }

表明:JSP頁面的聲明部分將轉換成對應Servlet的成員變量或成員方法。
注意:
1.JSP聲明部分定義的變量和方法可以使用private,public等訪問控制修飾符,也可使用static修飾,將其變成類屬性和類方法。但是不能使用abstract修飾聲明部分的方法,因爲抽象方法將導致JSP對應Servlet變成抽象類,導致無法實例化。
2.打開多個瀏覽器刷新該頁面,發現所有客戶端訪問的count將是連續的,即所有客戶端共享了同一個count變量。這是因爲:JSP頁面會編譯成一個Servlet類,每個Servlet在容器中只有一個實例;在JSP中聲明的變量是成員變量,成員變量只在創建實例時初始化,該變量的值將一直存在,直到實例銷燬。
同時info()方法的值也可以正常輸出。因爲JSP聲明額方法其實是在JSP編譯中生成的Servlet的實例方法。

5 輸出JSP表達式:

5.1 輸出JSP表達式格式:

<%= 表達式 %>

例1:使用輸出表達式的方式輸出變量和方法返回值。

</head>
    <%!
        //聲明一個整形變量
        private int count;
        //聲明一個方法
        public String info(){
            return "hello";
        }
    %>
  <body>
    <!-- 使用表達式輸出變量值 -->
    <%=count++ %>
    <br>
    <!-- 使用表達式輸出方法返回值 -->
    <%=info() %>
  </body>

使用輸出表達式語法替換了原來的out.println()輸出語句,頁面效果相同。表明:輸出表達式將轉換成Servlet裏的輸出語句。
注意:輸出表達式語法後不能有分號,否則會報錯

6 JSP腳本

所有可執行性Java代碼都可以通過JSP腳本嵌入HTML頁面。

<table bgcolor="#9999dd" border="1" width="300px">
    <!-- java腳本,這些腳本會對HTML的標籤產生作用 -->
        <%
            for(int i =0;i<10;i++){
                %>
                <!-- 上面的循環將控制<tr>標籤循環 -->
                <tr>
                    <td>循環值:</td>
                    <td><%=i %></td>
                </tr>
            <% }
        %>
 </table>
注意:
1.jsp腳本將轉換成Servlet_service方法的可執行代碼。這意味着在JSP小腳本部分也可以聲明變量,但聲明的是局部變量,並且不能使用private,public等訪問控制符修飾,也不可以使用static修飾。
2.jsp頁面裏的所有靜態內容將由service方法的輸出語句來輸出,這就是JSP腳本可以控制JSP頁面中靜態內容的原因。
3.java語法不允許在方法裏定義方法,所以jsp腳本不能定義方法。

這裏寫圖片描述

例1:JSP頁面執行數據庫查詢

<body>
    <%
        //註冊數據庫驅動
        Class.forName("com.mysql.jdbc.Driver");
        //獲取數據庫連接
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/test", "root", "root");
        //創建Statement
        Statement state =  conn.createStatement();
        //執行查詢
        ResultSet rs =  state.executeQuery("select name,money from t_account");
        %>
        <table bgcolor="#9999dd" border="1" width="300px">
            <!-- 遍歷結果 -->
            <% while(rs.next()){
                %>
                <tr>
                    <td><%=rs.getString(1) %></td>
                    <td><%=rs.getString(2) %></td>
                </tr>
            <% }%>
        </table>
  </body>

這裏寫圖片描述

注意:需要導入數據庫連接jar包;調用rs.next()方法,不是next屬性

7 JSP的3個編譯指令

JSP的編譯指令是通知JSP引擎的消息,它不直接生成輸出,編譯指令都有默認值,因此開發人員無需爲每個指令設置值。
常見的編譯指令如下3個:
page:該指令是針對當前頁面的指令
include:用於指定包含另一個頁面
taglib:用戶定義和訪問自定義標籤
格式如下:
<%@ 編譯指令名 屬性名="屬性值"%>

7.1 page指令

1:language:聲明當前jsp頁面使用的腳本語言的種類,因爲頁面是Jsp頁面,該屬性的值通常都是java,該屬性的默認值也是Java,所以通常無需設置。
2:extends:指定jsp頁面編譯所產生的java類所繼承的父類,或所實現的接口。
3:import:用來導入包,下面幾個包是默認自動導入的。默認導入的包有:java.lang.* , javax.servlet.* , javax.servlet.jsp* , java.servlet.http.*
4:session: 設定這個jsp頁面是否需要HTTP Session.
5:buffer: 指定輸出緩衝區的大小。輸出緩衝區的jsp內部對象:out用戶緩存JSP頁面對客戶端瀏覽器的輸出,默認是8kb,可以設置爲none,也可以設置爲其他的值,單位爲kb.
6:autoFlush:當輸出緩衝區即將溢出時,是否需要強制輸出緩衝區的內容。設置爲true時爲正常輸出;如果設置爲flash,則會在buffer溢出時候產生一個異常。
7:info:設置該jsp程序的信息,也可以看做其說明,可以通過Servlet.getServletInfo()方法獲取該值。如果在jsp頁面中,可以直接調用getServletInfo()方法獲取該值,因爲jsp頁面的實質是Servlet.
8:errorPage:指定錯誤處理頁面。如果本頁面產生了異常或錯誤,而該jsp頁面沒有對應的處理代碼,則會自動調用該屬性所指定的Jsp頁面。
因爲jsp內建了異常機制支持,所以Jsp可以不處理異常,即使是checked異常。
9:isErrorPage:設置本jsp頁面是否爲錯誤處理程序,如果該頁面本身已是錯誤處理頁面,則通常無需指定errorPage屬性。
10:contentType:用於設定生成網頁的文件格式或編碼字符集,即MIME類型和頁面字符集類型。默認的MIME類型是text/html,默認的字符集類型是ISO-8859-1.
11:pageEncoding:指定生成網頁的編碼字符集。

例1:使用info屬性指定了jsp頁面的描述信息,又使用getServletInfo()方法輸出該描述信息。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" info="this is a jsp"%>

 <body>
    <%=getServletInfo() %>
 </body>

這裏寫圖片描述

例2:errorPage屬性,該屬性指定了當本頁面發生異常時的異常處理頁面。

如果jsp頁面在運行中拋出未處理的異常,系統將自動跳轉到errorPage屬性指定的頁面;如果errorPage沒有指定錯誤頁面,系統則直接把異常信息呈現給客戶端瀏覽器。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" errorPage="error.jsp"%>

<body>
    <%
    int a = 6;
    int b = 0;
    int c = a/b;
    %>
</body>
錯誤顯示頁面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isErrorPage="true"%>

<body>
    <h1>系統出現異常</h1>
</body>

這裏寫圖片描述

7.2 include指令

    使用include指令,可以將一個外部文件嵌入到當前的jsp文件中,同時解析這個頁面中的jsp語句。這是個靜態的include語句,它會把目標頁面的其他編譯指令也包含進來,但動態的include則不會。
    include既可以包含靜態的文本,也可以包含動態的jsp頁面。靜態的include編譯指令會將被包含的頁面加入到本頁面,融合成一個頁面,因此被包含頁面甚至不需要是一個完整的頁面。

格式如下:

包含頁面1:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>測試page指令的info屬性</title>
  </head>
  <body>
    <%@ include file="index1.jsp" %>
  </body>
</html>
被包含頁面2:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>測試page指令的info屬性</title>
  </head>
  <body>
    <h2>天氣不錯</h2>
  </body>
</html>

注意:被包含頁面不能定義path和basePath 變量,否則會報錯:Duplicate local variable path(重複的局部變量)

如果被嵌入的文件經常需要修改,建議使用<jsp:include>操作命令,因爲它是動態的include語句。
對應的Servlet類:
 out.write("\r\n");
 out.write("\r\n");
 out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
 out.write("<html>\r\n");
 out.write("  <head>\r\n");
 out.write("    <base href=\"");
 out.print(basePath);
 out.write("\">\r\n");
 out.write("    <title>測試page指令的info屬性</title>\r\n");
 out.write("  </head>\r\n");
 out.write("  <body>\r\n");
 out.write("  \t");
 out.write("\r\n");
 out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
 out.write("<html>\r\n");
 out.write("  <head>\r\n");
 out.write("    <base href=\"");
 out.print(basePath);
 out.write("\">\r\n");
 out.write("    <title>測試page指令的info屬性</title>\r\n");
 out.write("  </head>\r\n");
 out.write("  <body>\r\n");
 out.write("  \t<h2>天氣不錯</h2>\r\n");
 out.write("  </body>\r\n");
 out.write("</html>\r\n");
 out.write("\r\n");
 out.write("  </body>\r\n");
 out.write("</html>\r\n");

    可以看出,1頁面已經完全將2頁面的代碼融入到1頁面中。其中被包含的代碼並不是由1頁面所生成的,而是由2頁面生成的。也就是說,2頁面的內容被完全融入到1頁面所生成的Servlet中,這就是靜態包含意義:包含頁面在編譯時將完全包含了被包含頁面的代碼。
注意:靜態包含還會將被包含頁面的編譯指令也包含進來,如果兩個頁面的編譯指令衝突,那麼頁面就會出錯。

8 JSP的7個動作指令

動作指令與編譯指令不同,編譯指令是通知Servlet引擎的處理消息,而動作指令只是運行時的動作。編譯指令在將JSP編譯成Servlet時起作用;而處理指令通常可替換成JSP腳本,它只是JSP腳本的標準化寫法。
JSP動作指令主要有如下7個:
1.jsp:forward:  執行頁面轉向,將請求的處理轉發到下一個頁面。
2.jsp:param:    用於傳遞參數,必須與其他支持參數的標籤一起使用
3.jsp:include:  用於動態引入一個jsp頁面
4.jsp:plugin:   用於下載JavaBeanApplet到客戶端執行
5.jsp:useBean:  創建一個JavaBean的實例
6.jsp:setProperty:  設置JavaBean實例的屬性值 
7.jsp:getProperty:輸出JavaBean實例的屬性值

8.1 forward指令

    forward指令用於將頁面響應轉發到另外的頁面。既可以轉發到靜態的HTML頁面,也可以轉發到動態的jsp頁面,或者轉發到容器中的Servlet中。
指令格式
1:對於jsp1.0:
<jsp:forward page="{relativeURL|<%=expression %>}"/>
2:對於jsp1.1以上規範
<jsp:forward page="{relativeURL|<%=expression %>}">
        {<jsp:param.../>}
</jsp:forward>

第二種語法用於在轉發時增加額外的請求參數,增加的請求參數的值可以通過HttpServletRequest類的getParameter()方法獲取。

例1:使用forward動作指令來轉發用戶請求

初始頁面:
<body>
    <jsp:forward page="forward_result.jsp">
        <jsp:param value="23" name="age"/>
    </jsp:forward>
</body>

轉發頁面:
<body>
    <%=request.getParameter("age") %>
</body>

結果顯示:
23

注意:
1.從上面的結果可以看出:執行forward指令時,用戶請求的地址依然沒有發生改變,但頁面內容卻完全變爲forward目標頁的內容。
2.執行forwardd指令轉發請求時,客戶端的請求參數不會丟失。

例2:執行forward時不會丟失請求參數

表單頁面:
 <body>
    <form id="login" method="post" action="index11.jsp">
        <input type="text" name="username">
        <input type="submit" value="login"> 
    </form>
 </body>

forward指令頁面:
<body>
    <jsp:forward page="forward_result.jsp">
        <jsp:param value="23" name="age"/>
    </jsp:forward>
</body>

轉發到頁面:
<body>
    <%=request.getParameter("age") %>
    <%=request.getParameter("username") %>
</body>

結果顯示:
23 lijisheng

結論:
1.在最終頁面不僅可以輸出forward指令增加的請求參數,還可以看到表單裏username表單域對應的請求參數,這表明執行forward時不會丟失請求參數。
2.從表面上看,<jsp:forward.../>指令給人一種感覺,他是將用戶請求“轉發”到額另一個新頁面,但實際上,<jsp:forward.../>並沒有重新向新頁面發送請求,它只是完全採用新頁面來對用戶生成響應--請求依然是一次請求,所以請求參數,請求屬性都不會丟失。

8.2 include指令

    include指令是一個動態include指令,也用於包含某個頁面,它不會導入被導入頁面的編譯指令,僅僅將被導入頁面等的body內容插入本頁面。
語法格式:
<jsp:include page="{relativeURL|<%=expression %>}" flush="true"/>
或者
<jsp:include page="{relativeURL|<%=expression %>}" flush="true">
        <jsp:param value="paramValue" name="paramName"/>
</jsp:include>

    其中flush屬性用於指定輸出緩存是否轉移到被導入文件中。如果指定爲true,則包含在被導入文件中,如果指定爲false,則包含在原文件中。對於JSP1.1舊版本,只能設置爲false.
    第二種語法格式,則可在被導入頁面中加入額外的請求參數。

例1:動態導入

<body>
    <jsp:include page="index1.jsp"></jsp:include>
</body>
Servlet頁面展示
 out.write("  <body>\r\n");
 out.write("   \t");
 org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "index1.jsp", out, false);
 out.write("\r\n");
 out.write("  </body>\r\n");
 out.write("</html>\r\n");

注意:動態導入只是使用一個include方法來插入目標頁面的內容,而不是將目標頁面完全融入本頁面中。

例2:有參數的動態導入

<body>
    <jsp:include page="index1.jsp">
        <jsp:param value="rain" name="like"/>
    </jsp:include>
</body>


<body>
    <%=request.getParameter("like") %>
</body>

結果展示:
rain

動態導入和靜態導入有三點區別:

1.靜態導入時將被導入頁面的代碼完整融入,兩個頁面融合成一個整體Servlet,而動態導入則在Servlet中使用include方法來引入被導入頁面的內容。
2.靜態導入時被導入頁面的編譯指令會起作用,而動態導入時被導入頁面的編譯指令則失去作用,只是插入被導入頁面的body內容。
3.動態包含還可以增加額外的參數。
提示:forward動作指令和include動作指令十分相似,都是使用方法來引入目標頁面。區別在於:forward拿目標頁面替換原有頁面,而include則拿目標頁面插入原有原有頁面。

8.3 useBean,setProperty,getProperty命令

1.這3個指令都是與JavaBean相關的指令,其中useBean指令用於在JSP頁面初始化一個Java實例;setProperty指令用於爲JavaBean實例的屬性設置值;getProperty指令用於輸出JavaBean實例的屬性。
2.如果多個JSP頁面中需要重複使用某段代碼,我們可以把這段代碼定義成Java類的方法,然後讓多個JSP頁面調用該方法即可,這樣可以達到很好的代碼複用。

useBean的語法格式如下:

<jsp:useBean id="name"  class="classname" scope="page|request|session|application"/>

    其中,id屬性是JavaBean的實例名,class屬性確定JavaBean的實現類。scope屬性用於指定JavaBean實例的作用範圍,該範圍有如下四個值。
    1.page:該JavaBean實例僅在該頁面有效。
    2.request:該JavaBean實例在本次請求中有效。
    3.session:該JavaBean實例在本次session中有效。
    4.application:該JavaBean實例在本應用內一直有效。

setProperty指令的語法格式如下:

<jsp:setProperty property="propertyName" name="BeanName" value="value"/>

其中,name屬性確定需要設定JavaBean的實例名,property屬性確定需要設置的屬性名;value屬性則確定需要設置的屬性值。

getProperty指令的語法格式:

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

其中,name屬性確定需要輸出的JavaBean的實例名,property屬性確定需要輸出的屬性名。

例1:使用這3個動作指令來操作JavaBean

<body>
   <jsp:useBean id="p1" class="test.Persion" scope="page"></jsp:useBean>
   <jsp:setProperty property="name" name="p1" value="lijisheng"/>
   <jsp:setProperty property="age" name="p1" value="23"/>
   <jsp:getProperty property="name" name="p1"/><br>
   <jsp:getProperty property="age" name="p1"/>
</body>

結果顯示:
lijisheng
23
    注意:對於上面的JSP頁面的setProperty和getProperty標籤而言,他們都要求根據屬性名來操作JavaBean的屬性。實際上setProperty和getProperty要求的屬性名,與Java類中定義的屬性有一定的差別。
    例如:setProperty和getProperty需要使用name屬性,但JavaBean中是否真正定義來了name屬性並不重要,重要的是在JavaBean中提供了setName()和getName()方法即可。
    事實上,當頁面使用setProperty和getProperty標籤時,系統底層是調用setName()和getName()方法來操作Persion實例的屬性的。

例2:不使用這三個標籤實現同樣功能

 <body>
   <%
   Persion p1 = new Persion("lijisheng",20);
   //將p1放到page範圍中
   pageContext.setAttribute("p1", p1);
   %>
   <%=p1.getName() %><br>
   <%=p1.getAge() %>
 </body>

使用useBean標籤時,除在頁面腳本中創建了JavaBean實例之外,該標籤還會將JavaBean實例放入scope中。

pageContext.setAttribute("p1", p1);
request.setAttribute("p1", p1);
session.setAttribute("p1", p1);
application.setAttribute("p1", p1);

8.4 plugin指令

    plugin指令主要用於下載服務器端的JavaBean或Applet到客戶端執行。由於程序在客戶端執行,因此客戶端必須安裝虛擬機。

    提示:實際上現在很少使用Applet,即使需要Applet,我們也可以使用支持Applet的HTML標籤,所以使用場景不多。

8.5 param指令

    param指令用於設置參數值,這個指令本身不能單獨使用,因爲單獨的param指令沒有實際意義。param指令可以與以下三個指令相結合。
    1.jsp:include
    param指令用於將參數值傳入被導入的頁面
    2.jsp:forward
    param指令用於將參數值傳入被轉向的頁面
    3.jsp:plugin
    param指令用於將參數值傳入頁面中的JavaBean實例或Applet實例。

param指令語法格式如下:

<jsp:param value="paramValue" name="paramName"/>

9 JSP腳本中的9個內置對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章