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>