JSP之include動態包含與靜態包含
include 有兩種包含方式,一種是指令包含,也就是靜態包含;另一種是標籤包含,也就是動態包含。
靜態包含:<%@include file="包含檔案"%>
靜態包含的方式會直接將包含檔案的程式碼融入到主檔案的include指令處,然後對主檔案進行編譯、執行。所以,靜態包含只會生成主檔案jsp對應的一個java檔案。
示例:
test.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>練習</title> <script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.js"></script> </head> <body> <% int x=5; %> <%@include file="test2.jsp"%> </body> </html>
test2.jsp :
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
</head>
<body>
<%
int a=6;
%>
<%=x%>
</body>
</html>
啟動tomcat訪問test1.jsp執行結果:
5
work目錄下生成的檔案(發現只對test.jsp進行了編譯):
開啟test_jsp.java(其中一個部分程式碼):
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("\r\n"); out.write("<html>\r\n"); out.write("\r\n"); out.write("<head>\r\n"); out.write(" <title>練習</title>\r\n"); out.write(" <script src=\"http://apps.bdimg.com/libs/jquery/1.6.4/jquery.js\"></script>\r\n"); out.write("\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); int x=5; out.write('\r'); out.write('\n'); out.write("\r\n"); out.write("\r\n"); out.write("<html>\r\n"); out.write("<head>\r\n"); out.write("\r\n"); out.write("</head>\r\n"); out.write("<body>\r\n"); int a=6; out.write('\r'); out.write('\n'); out.print(x); out.write("\r\n"); out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>\r\n"); out.write("\r\n"); out.write("</body>\r\n"); out.write("</html>\r\n"); out.write("\r\n");
可以看到,兩個jsp檔案融為一個被編譯了。所以,這兩個jsp檔案不能有衝突的地方。比如test.jsp檔案定義了int x=5,在test2.jsp檔案就不能再定義int x。jsp開頭的page指令內容也要一致,不能有衝突,否則也會報錯。
另外,這兩個jsp檔案既然可以看成是一個合體的jsp檔案,那麼伺服器傳遞過來的引數(比如request)它們就都能接收的到。
動態包含:<jsp:include page=" 包含檔案">
動態包含的方式不是先把兩個jsp檔案的程式碼融合再編譯,而是執行到了include語句的時候才觸發包含檔案的編譯、執行,並把執行的結果包含進來。所以,這裡會產生兩個java檔案。由於兩個jsp檔案是相互獨立編譯執行的,所以它們的變數是不共享的。
示例:
test.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>練習</title>
<script src="http://apps.bdimg.com/libs/jquery/1.6.4/jquery.js"></script>
</head>
<body>
<%
int x=5;
%>
<jsp:include page="test2.jsp"></jsp:include>
</body>
</html>
test2.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
</head>
<body>
<%
int a=6;
%>
<%=x%>
</body>
</html>
訪問test.jsp執行結果:
由於在test.jsp中定義的變數x在test2.jsp中是訪問不到的,所以丟擲異常。於是,我們把test2.jsp中的x改成a,再執行,看看work目錄下生成的檔案:
開啟test_jsp.java:
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("\r\n");
out.write("<html>\r\n");
out.write("\r\n");
out.write("<head>\r\n");
out.write(" <title>練習</title>\r\n");
out.write(" <script src=\"http://apps.bdimg.com/libs/jquery/1.6.4/jquery.js\"></script>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
int x=5;
out.write('\r');
out.write('\n');
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "test2.jsp", out, false);
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
可以看到,是直接用了include()方法將test2.jsp檔案執行的返回結果包含進來,並且這裡將request和response都作為引數傳遞給了test2.jsp,所以這兩個jsp檔案同樣都能接收到來自伺服器傳遞過來的引數(比如request)。
再開啟test2_java.jsp(內容完全就是對test2.jsp的編譯):
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("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
int a=6;
out.write('\r');
out.write('\n');
out.print(a);
out.write("\r\n");
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
使用總結:
靜態包含執行效率會更快,但是有可能發生變數衝突的問題。另外使用靜態包含如果包含的檔案發生了變化的話,所有包含它的servlet都要重新編譯更新,這是一個很大的代價。通常情況下使用動態包含比較多。對頁首頁尾、導航欄之類的靜態內容我們就用靜態包含,對資料庫實時查詢、時間戳等動態內容我們就用動態包含。