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都要重新编译更新,这是一个很大的代价。通常情况下使用动态包含比较多。对页眉页脚、导航栏之类的静态内容我们就用静态包含,对数据库实时查询、时间戳等动态内容我们就用动态包含。