JSP(Java Server Page)
JSP簡單的說就是HTML+JAVA代碼,檔案尾碼為.jsp的檔案。
JSP和Servlet是JavaEE的重要基礎,看起來JSP和Servlet是兩個完全不同的東西,但是JSP其實就是Servlet的一種形式,JSP最終需要被編譯成Servlet;
JSP頁面必須部署到web容器中才能夠訪問,因為單單的JSP頁面時沒有用處的;必須要轉換成Servlet才能夠使用;
JSP是物件導向的,因為最後會變成Servlet,而Servlet是一個類,這個可能不好理解,下面會有講解.
而使用者訪問JSP頁面看到的輸出時Servlet輸出資料流的結果;
JSP可以不處理異常,因為如果產生異常有兩種處理方法:
1.在瀏覽器頁面顯示;
2.跳轉到errorPage;
JSP到Servlet的轉換當第一次訪問某個JSP檔案時,web伺服器會將JSP檔案轉換成Servlet,再由Servlet提供輸出資料流將HTML輸出給客戶.因此客戶接觸的只是HTML而已,而JSP的處理過程都是在伺服器完成的;注意:每個Servlet類的對象在容器中只有一個,因此每個客戶訪問的同一個JSP頁面都是一個Servlet對象;
假設有null.jsp檔案,此檔案內容為空白,如下所示:
<%@ page contentType="text/html;charset=utf-8" pageEncoding="utf-8" info="This is a JSP " %><html><body></body></html>
在tomcat的work目錄中會產生null_jsp.java和null_jsp.class,null_jsp.java的代碼如下:
package org.apache.jsp;import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;//HttpJspBase是Servlet的子類/*此類主要有三個方法組成:1.init(); 初始化2.destroy(): 銷毀3.service(); 接收用戶端請求並處理*/public final class null_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { public String getServletInfo() { return "This is a JSP "; } private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory(); private static java.util.List<String> _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.List<String> 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 HttpServletRequest request, final HttpServletResponse response) throws java.io.IOException, ServletException {//產生JSP內建對象 final PageContext pageContext; HttpSession session = null; final ServletContext application; final ServletConfig config; JspWriter out = null; final Object page = this; JspWriter _jspx_out = null; 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;//輸出JSP頁面中的顯示 out.write("\r\n"); out.write("<html>\r\n"); out.write("\t<body>\r\n"); out.write("\r\n"); out.write("\t</body>\r\n"); out.write("</html>"); } catch (Throwable t) { if (!(t instanceof 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); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } }}
從以上代碼就可以很清晰地看出JSP和Servlet的關係了,JSP編寫的<%%> <%=%> 和 html代碼都是在Service函數中實現;
而<%! %>中的代碼作為Servlet類的成員變數和成員方法;
JSP內建對象就是在這個檔案中被建立的。
一、注釋
一種語言都會有注釋,而這裡JSP有兩種類型的注釋,使用者能夠查看網頁原始碼看見顯式注釋,而看不見隱式注釋。
(1)顯式注釋:<!--顯式注釋 -->
(2)隱式注釋:
//隱式注釋
/*隱式注釋*/
<%--隱式注釋 --%>
二、在HTML中插入JAVA代碼方法:1.Scriptlet:指令碼小程式
(1)<%...%>:可以插入一些語句。
舉例:<% out.println("<h2>Hello world</h2>"); %>表明向網頁輸出一個Hello world語句。
(2)<%! ... %>:只能放置全域變數、全域常量、類、函數。
舉例:
<%!
public static final String INFO="HELLO WORLD";
class Person{
.....
}
%>
注意:<%! %>中不能使用內建對象!
(3)<%= ... %>:只能放置一個變數、常量。
舉例:<%="Hello world"%>
2.<jsp:scriptlet>標籤
在<jsp:scriptlet></jsp:scriptlet>中插入語句即可。
三、編譯指令編譯指令模板:<%@ 指令 %>1.page指令
page指令放在jsp檔案的最上方,描述一些資訊,以<%@ page 屬性="值"%>的形式出現;
屬效能夠有:
(1)contentType:網頁的內容類型,即MIME類型,通常為 contentType="text/html";裡面還能設定字元集,經常為 contentType="text/html;charset=GBK";
(2)language:表示指令碼所用語言,目前只能為 language="java";
(3)pageEncoding:表示頁面的編碼方式,通常為 pageEncoding="GBK";
(4)import:表示在寫java代碼時需要匯入的包,比如需要使用JDBC,則需要匯入java.sql.*,則為 import= "java.sql.*";
(5)errorPage:當錯誤時需要跳轉到的頁面,但是同時那個錯誤頁必須設定isErrorPage屬性。
注意:通常在錯誤頁中需要首先設定response.setStatus(200); 錯誤頁跳轉是伺服器跳轉
JSP不需要處理異常的原因就是因為有errorPage屬性,errorPage屬性類似於catch{ },有異常,則跳轉到錯誤頁面
(6)isErrorPage:如果某頁為錯誤頁,則必須設定為 isErrorPage="true";
在整個虛擬目錄中添加錯誤頁、異常處理頁等:
在虛擬目錄中的web.xml中添加:
<error-page>
<error-code>404</error-code>
<location>/error/clientError.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error/exception.jsp</location>
</error-page>
注意:配置完web.xml後需要重啟tomcat伺服器;
綜合舉例:
<%@ page language="java" contentType="text/html;charset=GB2312" pageEncoding="GB2312" import="java.util.*" errorPage="error.html"%>
注意點:
(1)如果需要讓頁面識別中文,則必須設定pageEncoding屬性。
(2)MIME類型:key--->value,key表示檔案尾碼,而value表示開啟這個尾碼的應用程式類型。在tomcat的conf/web.xml中可以查看MIME類型及其開啟檔案。
比如,如果設定為application/msword,則說明用word開啟,鍵入網頁後會先下載,下載後能夠用word開啟。
更改名稱:通過response.setHeader("Content-Disposition","attachment;filename=xiazdong.doc"); 即可;
(3)html和htm是一樣的。
(4)pageEncoding指定JSP的頁面編碼,而contentType是用戶端的編碼。
2.include指令
<%@ include file="filename"%>
這是靜態包含,即將被包含的檔案融入成為一個檔案,因此從tomcat產生的java檔案中可以看出。
而動態包含則是調用了include函數將一個檔案包含進來,而不是融為一體;
以上區別在外部是看不出的,需要觀察自動產生的Servlet類才能看出;
靜態包含的缺點就是不能傳遞參數;
四、用戶端跳轉和伺服器跳轉:
(1)用戶端跳轉:這種形式的跳轉會使得地址欄的地址改變為跳轉的地址,比如a.jsp--->b.jsp,原本地址欄是a.jsp,跳轉之後地址欄變成b.jsp,則這種跳轉屬於用戶端跳轉。
(2)伺服器跳轉:跳轉後地址欄沒有改變,並且不會丟失請求參數。比如a.jsp-->b.jsp,則地址欄一直維持a.jsp,則稱為伺服器跳轉。
而我們剛才遇到的errorPage跳轉就是伺服器跳轉。
五、資料庫連接:
這裡以mySQL為例,配置步驟為把mySQL的JDBC驅動程式放到tomcat/lib中,通常我們把第三方的jar包都放在這裡。
需要注意的是需要加入try語句,其他的和JDBC差不多,就不介紹了。
六、包含指令(include)
簡單的來說就是包含一個html/jsp/htm檔案,包含分為兩種:
(1)靜態包含:先包含,再編譯。形如:<%@ include file="demo.html"%>
舉例:有a.jsp、b.jsp、c.jsp,在a.jsp中靜態包含b.jsp、c.jsp意味著先將b.jsp、c.jsp的代碼都寫入a.jsp,然後編譯產生class檔案。
(2)動態包含:對於一個動態網頁面,先編譯,後包含。形如:<jsp:include page="demo.jsp"/>
舉例:有a.jsp、b.jsp、c.jsp,在a.jsp中動態包含b.jsp、c.jsp意味著編譯產生class檔案,然後再包含在一起。
動態包含還能夠傳遞參數,注意,是包含頁面--->被包含頁面,形如:
<jsp:include page = "demo.jsp"/>
<jsp:param name="name" value="xiazdong"/>
<jsp:param name="age" value="20"/>
</jsp:include>
被包含頁通過request.getParameter()接收。
七、跳轉指令(<jsp:forward>) 伺服器跳轉
(1)沒傳遞參數的跳轉指令:
<jsp:forward page="demo.jsp"/>
(2)傳遞參數的跳轉指令:
<jsp:forward page="demo.jsp">
<jsp:param name="name" value="xiazdong"/>
<jsp:param name="age" value="20">
</jsp:forward>
參數通過request.getParameter("");接收,其實由於此跳轉為伺服器端跳轉,所以也可以通過設定request內建對象設定屬性進行傳遞,JSP內建對象後面會講到。
補充:JSP生命週期
1.web容器讀取web.xml中的配置資訊;
2.當客戶發出jsp請求時,JSP翻譯成Servlet,並編譯成class檔案;
3.容器載入Servlet;
4.容器執行個體化Servlet,並調用jspInit()方法;
5.容器建立Servlet線程,調用Service方法;
6.調用destroy();