1. 程式人生 > >談談jsp中的靜態包含和動態包含

談談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物件。

靜態包含,通過看jspservlet的原始碼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骨架的標籤,如htmlbody,要確保整合後的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"/>

其實,動態包含,父頁面和子頁面是通過requestresponse進行通訊的,被包含的頁面做的是服務端跳轉,request.getRequestDispatcher(),頁面是在請求的時候動態載入的,父頁面的requestresponseout傳入了子頁面中,理論上說,子頁面的引數應該大於等於父頁面的引數。

看下面一個例子:

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通過requestreponse進行通訊。如果被包含的檔案是靜態的,那麼這種情況和<%@include>就很相似,只生成了一個Servlet,但是他們之間沒有進行簡單的嵌入,而依然是通過requestreponse進行的通訊。

附件

此處簡述一下<jsp:include/>和<c:import/>的區別:

二者都是動態載入,但jsp:include只能包含當前web app下的頁面,c:import則可以從外部容器中載入內容,可以指定任何一個url地址。另外jsp:include和c:import可以分別使用jsp:param和c:param設定引數來控制要包含的頁面。