1. 程式人生 > 其它 >JSP:JSP基礎篇——未完

JSP:JSP基礎篇——未完

技術標籤:JAVA/JSP

1,JSP的4種基本語法

1.1,JSP註釋

JSP註釋用於標註程式開發過程中的開發提示,不會輸出到客戶端(使用者無法通過檢查原始碼而看到註釋)。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
  <div>
    <%--我是JSP註釋--%>
    <!--我是HTML註釋-->
  </div>
</body>
</html>

1.2,JSP宣告

JSP宣告用於宣告變數和方法。在JSP宣告中宣告方法看起來很特別,似乎不需要定義就可直接定義方法,方法可以脫離類獨立存在。實際上,JSP宣告將轉換成對應Servlet的成員變數或成員方法,因此JSP宣告依然符合Java語法。

JSP宣告的語法格式:<%! 宣告部分 %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<div>
    <%!
        public int count;

        public String info() {
            return "hello";
        }
    %>
    <%
        out.println(count++);
        out.println(info());
    %>
</div>
</body>
</html>

由於JSP宣告語法定義的變數和方法對應於Servlet類的成員變數和方法,所以JSP宣告部分定義的變數和方法可以使用private、public等訪問控制修飾符,也可以使用static修飾,將其變成類屬性和類方法,但不能使用abstract修飾宣告部分的方法,因為抽象方法將導致JSP對應Servlet變成抽象類,從而導致無法例項化。

開啟多個瀏覽器頁面,甚至可以在不同機器上開啟瀏覽器來重新整理該頁面,將發現所有不同的客戶端訪問的count是連續的,即所有客戶端共享同一個count變數。這是因為:JSP頁面會編譯生成一個Servlet類,每個Servlet在容器中只有一個例項;在JSP中宣告的變數是成員變數,成員變數只在建立例項時初始化,該變數的值將一直儲存,直到例項銷燬。

值得注意的是,info()的值也可正常輸出。因為JSP宣告的方法其實是在JSP編譯中生成的Servlet的例項方法——Java裡的方法是不能獨立存在的,即使在JSP頁面中也不行。JSP宣告中獨立存在的方法,只是一種假象。

1.3,輸出JSP表示式

JSP提供了一種輸出表達式值的簡單方法,輸出表達式值的語法格式如下:

<%=表示式>
<div>
    <%!
        public int count;

        public String info() {
            return "hello";
        }
    %>
    <%=count++%>
    <%=info()%>
</div>

輸出表達式語法代替了原來的out.print輸出語句,該頁面的執行效果與前一個程式沒有區別。輸出表達式語法後不能有分號。

1.4,JSP指令碼

JSP腳本里面可以包含任何可執行的Java程式碼,所有可執行的Java程式碼都可以通過JSP指令碼嵌入HTML。

<div>
    <table bgcolor="#9999dd" border="1" width="300px">
        <%
            for (int i=0;i<10;i++){
        %>
        <tr>
            <td>迴圈值:</td>
            <td><%=i%></td>
        </tr>
        <%
            }
        %>
    </table>
</div>

開啟編譯後的程式碼:

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("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("<head>\n");
      out.write("    <title>Test</title>\n");
      out.write("</head>\n");
      out.write("<body>\n");
      out.write("<div>\n");
      out.write("    <table bgcolor=\"#9999dd\" border=\"1\" width=\"300px\">\n");
      out.write("        ");

            for (int i=0;i<10;i++){
        
      out.write("\n");
      out.write("        <tr>\n");
      out.write("            <td>迴圈值:</td>\n");
      out.write("            <td>");
      out.print(i);
      out.write("</td>\n");
      out.write("        </tr>\n");
      out.write("        ");

            }
        
      out.write("\n");
      out.write("    </table>\n");
      out.write("</div>\n");
      out.write("</body>\n");
      out.write("</html>\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指令碼將轉換成Servlet裡_jspService方法的可執行程式碼。這意味著在JSP小指令碼部分也可以宣告變數,但在JSP指令碼部分宣告的變數是區域性變數,但不能用private、public等訪問控制符修飾,也不可使用static修飾。

實際上不僅JSP小指令碼部分會轉換成_jspService方法裡的可執行程式碼,JSP頁面裡的所有靜態內容都將由_jspService方法裡輸出語句來輸出,這就是JSP指令碼可以控制JSP頁面中靜態內容的原因。由於JSP指令碼將轉換成_jspService方法裡的可執行性程式碼,而Java不允許在方法裡定義方法,所以JSP腳本里不能定義方法。

<%@ page import="java.sql.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<div>
    <table bgcolor="#9999dd" border="1" width="300px">
        <%
            Class.forName("com.mysql.jdbc.Driver");
            Connection  connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "123456");
            String sql = "select * from student";
            Statement statement = connection.createStatement();
            ResultSet resultset = statement.executeQuery(sql);
            while (resultset.next()){
        %>
        <tr>
            <td><%=resultset.getString(1)%></td>
            <td><%=resultset.getString(2)%></td>
        </tr>
        <%
            }
        %>
    </table>
</div>
</body>
</html>

上面連線資料庫需要用到資料庫驅動架包,需要將驅動複製到tomcat的lib下面:E:\apache\apache-tomcat-8.5.46\lib

2,JSP的三個編譯指令

JSP的編譯指令是通過JSP引擎的訊息,它不直接生成輸出。編譯指令都有預設值,因此開發人員無須為每個指令設定值。

  • page:該指令是針對當前頁面的指令
  • include:用於指定包含另一個頁面
  • taglib:用於定義和訪問自定義標籤
編譯指令的語法格式:<%@ 編譯指令名 屬性名="屬性值" ...%>

2.1,page指令

page指令通常位於JSP頁面的頂端,一個JSP頁面可以使用多條page指令。

<%page
[language="Java"]聲明當前JSP頁面使用的指令碼語言的種類,因為頁面是JSP頁面,該屬性的值通常都是java,該屬性的預設值也是java,所以通常無需設定。
[extends="package.class"]指定JSP頁面編譯所產生的Java類所繼承的父類,或所實現的介面。

[import="package.class"]

用來匯入包。下面幾個包是自動匯入的,不需要,不需要顯式匯入。預設匯入的包有:java.lang.*、javax.servlet.*、javax.servlet.jsp.*、javax.servlet.http.*。
[session="true|false"]設定這個JSP頁面是否需要HTTP Session。
[buffer="none|8KB|size KB"]指定輸出緩衝區大小。輸出緩衝區的JSP內部物件:out用於快取JSP頁面對客戶瀏覽器的輸出,預設值為8KB,可以設定為none,也可以設定為其他的值,單位為KB。
[autoFlush="true|false"]當輸出緩衝區即將溢位時,是否需要強制輸出緩衝區的內容。設定為true時為正常輸出;如果設定為false,則會在buffer溢位時產生一個異常。
[isThreadSafe="true|false"]設定執行緒是否安全。
[info="text"]設定該JSP程式的資訊,也可以看做其說明,可以通過Servlet.getServletInfo()方法獲取該值。如果在JSP頁面中,可直接呼叫getServletInfo()方法獲取該值,因為JSP頁面的實質就是Servlet。
[errorPage="relativeURL"]指定錯誤處理頁面。如果本頁面產生了異常或錯誤,而該JSP頁面沒有對應的處理程式碼,則會自動呼叫該屬性所指定的JSP頁面。
[contentType="mimeType[;charset=characterSet]"|"text/html;charSet=ISO-8859-1"]
用於設定生成網頁的檔案格式和編碼字符集,即MIME型別和頁面字符集型別,預設的MIME型別是text/html;預設字符集時ISO-8859-1.
[pageEncoding="ISO-8859-1"]指定生成的網頁的編碼字符集
[isErrorPage="true|false"]是否採用ErrorPage
%>
<%@ page import="java.sql.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" language="java" errorPage=""%>

2.2,include指令

使用include指令,可以將一個外部檔案嵌入到當前JSP檔案中,同時解析這個頁面中的JSP語句(如果有的話)。這個靜態的include語句,它會把目標頁面的其他編譯指令也包含進來。

include既可以包含靜態的文字,也可以包含動態的JSP頁面。靜態的include編譯指令會將被包含的頁面加入頁面,融合成一個頁面,因此被包含頁面甚至不需要是一個完整的頁面。

include編譯指令的語法如下:<%@include file="relativeURLSpec">
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Test</title>
</head>
<body>
<div>
    <%@include file="detail.jsp"%>
</div>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.sql.*" %>
<table bgcolor="#9999dd" border="1" width="300px">
    <%
        Class.forName("com.mysql.jdbc.Driver");
        Connection  connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "123456");
        String sql = "select * from student";
        Statement statement = connection.createStatement();
        ResultSet resultset = statement.executeQuery(sql);
        while (resultset.next()){
    %>
    <tr>
        <td><%=resultset.getString(1)%></td>
        <td><%=resultset.getString(2)%></td>
    </tr>
    <%
        }
    %>
</table>

2.3,taglib指令

後續補充

3,JSP的7個動作指令

動作指令與編譯指令不同,編譯指令是通知Servlet引擎的處理訊息,而動作指令只是執行時的動作。編譯指令在將JSP編譯成Servlet時起作用;而處理指令通常可替換成JSP指令碼,它只是JSP指令碼的標準化。

  • jsp:forward:執行頁面轉向,將請求的處理轉發到下一個頁面。
  • jsp:param:用於傳遞引數,必須與其他支援引數的標籤一起使用。
  • jsp:include:用於動態引入一個JSP頁面。
  • jsp:plugin:用於下載JavaBean或Applet到客戶端執行。
  • jsp:useBean:建立一個JavaBean的例項。
  • jsp:setProperty:設定JavaBean例項的屬性值。
  • jsp:getProperty:輸出JavaBean例項的屬性值。

3.1,forward指令

forward指令用於將頁面響應轉發到另外的頁面。既可以轉發到靜態的HTML頁面,也可以轉發到動態的JSP頁面,或者轉發到容器中的Servlet。

JSP1.0:<jsp:forward page="{relativeURL|<%=expression%>}">
JSP2.0:轉發時增加了額外的請求引數。增加的請求可以通過HttpServletRequest類的getParameter()方法獲取。
<jsp:forward page="{relativeURL|<%=expression%>}">
    {<jsp:param.../>}
</jsp>