談談jsp中的靜態包含和動態包含
靜態包含
語法:<%@ include file=""%>
1、靜態包含的兩個jsp頁面,頭部設定必須保持一致。
index1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <div> 測試頁面index1 </div> <%@ include="index2.jsp" %> </body> </html>
index2.jsp
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<div>
測試index2
</div>
如上程式碼執行,報如下錯誤
故靜態包含,兩個檔案的編碼格式一定要保持一致。
2、靜態包含,file引數不能攜帶引數,file引數只能指定檔案路徑,如果攜帶引數,將找不到檔案路徑,導致程式報錯。
3、包含的jsp頁面和被包含的jsp頁面公用一個request物件。
靜態包含,通過看jsp轉servlet的原始碼index_jsp.java
out.write("\r\n"); out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n"); out.write("<title>Insert title here</title>\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); out.write("\t<div>\r\n"); out.write("\t\t測試頁面index1\r\n"); out.write("\t</div>\r\n"); out.write("\t"); out.write("\r\n"); out.write("<div>\r\n"); out.write("\t測試index2\r\n"); out.write("</div>"); out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>");
靜態包含,只會生成一個servlet,靜態內容直接作為輸出物件。
4、靜態包含,jsp先進行整合,再生成servlet的,故,靜態包含儘量不要在被包含的頁面出現html骨架的標籤,如html、body,要確保整合後的html符合W3C規範。
動態包含
語法:<jsp:include page=””/>
1、動態包含,如果包含的是靜態檔案(html),只會生成一個servlet類,如果包含的是動態檔案(jsp),會生成兩個檔案。
2、動態包含,可以傳遞引數,語法如下:
<jsp:include page="">
<jsp:param name="" value="" />
<jsp:param name="" value="" />
</ jsp:include >
也可以在page路徑上直接寫引數,如:
<jsp:include page="index2.jsp?b=2"/>
其實,動態包含,父頁面和子頁面是通過request、response進行通訊的,被包含的頁面做的是服務端跳轉,request.getRequestDispatcher(),頁面是在請求的時候動態載入的,父頁面的request,response、out傳入了子頁面中,理論上說,子頁面的引數應該大於等於父頁面的引數。
看下面一個例子:
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div>
測試頁面index1
<br>
引數a的值:<%=request.getParameter("a")%>
</div>
<jsp:include page="index2.jsp">
<jsp:param name="b" value="2" />
</jsp:include>
引數b的值:<%=request.getParameter("b")%>
</body>
</html>
index2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<body>
<div>
測試index2
<br>
引數a的值:<%=request.getParameter("a")%>
<br/>
引數b的值:<%=request.getParameter("b")%>
</div>
</body>
測試地址為:http://localhost:8080/jsp/index.jsp?a=2,執行結果:
測試頁面index1
引數a的值:2
測試index2
引數a的值:2
引數b的值:2
引數b的值:null
生成servlet的個數:
index_jsp.java
out.write("\r\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
out.write("<title>Insert title here</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\t<div>\r\n");
out.write("\t\t測試頁面index1\r\n");
out.write("\t\t<br>\r\n");
out.write("\t\t引數a的值:");
out.print(request.getParameter("a"));
out.write("\r\n");
out.write("\t</div>\r\n");
out.write("\t");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "index2.jsp" + "?" + org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("b", request.getCharacterEncoding())+ "=" + org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("2", request.getCharacterEncoding()), out, false);
out.write("\r\n");
out.write("\t\r\n");
out.write("\t引數b的值:");
out.print(request.getParameter("b"));
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>");
index2_jsp.java
out.write("\r\n");
out.write("<body>\r\n");
out.write("<div>\r\n");
out.write("\t測試index2\r\n");
out.write("\t<br>\r\n");
out.write("\t引數a的值:");
out.print(request.getParameter("a"));
out.write("\r\n");
out.write("\t<br/>\r\n");
out.write("\t引數b的值:");
out.print(request.getParameter("b"));
out.write("\r\n");
out.write("</div>\r\n");
out.write("</body>");
動態包含,可以傳遞引數,因為動態包含進行了一個request.getRequestDispatcher,進行了一次動態請求,最終的頁面都是通過out整合,輸出的一個完整的html,故包含的頁面儘量不要出現html骨架標籤,如上面的例子,index2.jsp中包含body標籤,就不是很合適。
總結
對於靜態包含,<%@include%>,中包含的檔案,只是簡單的嵌入到主檔案中,就是在jsp頁面轉化成Servlet時才嵌入到主檔案中,因為執行的結果是隻生成了一個Servlet。
而對於動態包含<jsp:incude>,如果被包含檔案是動態的,那麼就會生成兩個Servlet,也就是被包含檔案也要經過jsp引擎編譯執行生成一個Servlet,兩個Servlet通過request和reponse進行通訊。如果被包含的檔案是靜態的,那麼這種情況和<%@include>就很相似,只生成了一個Servlet,但是他們之間沒有進行簡單的嵌入,而依然是通過request和reponse進行的通訊。
附件
此處簡述一下<jsp:include/>和<c:import/>的區別:
二者都是動態載入,但jsp:include只能包含當前web app下的頁面,c:import則可以從外部容器中載入內容,可以指定任何一個url地址。另外jsp:include和c:import可以分別使用jsp:param和c:param設定引數來控制要包含的頁面。