1. 程式人生 > >JSP之include動態包含與靜態包含

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都要重新編譯更新,這是一個很大的代價。通常情況下使用動態包含比較多。對頁首頁尾、導航欄之類的靜態內容我們就用靜態包含,對資料庫實時查詢、時間戳等動態內容我們就用動態包含。