“<jsp:include page = ...>”和“<%@ include file = ...>”有什么区别?

112
两个标签都可以将一个页面的内容包含在另一个页面中。
那么这两个标签之间有什么确切的区别呢?
6个回答

112
在一个可重复使用的代码片段中,我使用指令<%@include file="reuse.html"%>,而在第二个代码片段中,我使用标准操作<jsp:include page="reuse.html" />
让可重复使用的文件中的代码如下:
<html>
<head>
    <title>reusable</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <img src="candle.gif" height="100" width="50"/> <br />
    <p><b>As the candle burns,so do I</b></p>
</body>

运行两个JSP文件后,您会看到相同的输出,并想知道指令动作标签之间是否有任何区别。但是,如果您查看这两个JSP文件生成的servlet,您将看到它们之间的差异。

使用指令时,您将看到以下内容:

out.write("<html>\r\n");
out.write("    <head>\r\n");
out.write("        <title>reusable</title>\r\n");
out.write("        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
out.write("    </head>\r\n");
out.write("    <body>\r\n");
out.write("        <img src=\"candle.gif\" height=\"100\" width=\"50\"/> <br />\r\n");
out.write("        <p><b>As the candle burns,so do I</b></p>\r\n");
out.write("    </body>\r\n");
out.write("</html>\r\n");
 

以下是第二个JSP文件中使用的标准动作的显示内容:
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "reusable.html", out, false);

现在您已经知道include指令会在翻译时插入reuse.html的源代码,但是动作标记会在运行时插入reuse.html的响应内容。

如果您仔细思考一下,每个动作标记<jsp:include>)都会带来额外的性能损失。这意味着您可以保证始终拥有最新的内容,但这增加了性能成本。


5
请问您能具体说明哪个输入的结果产生了哪个输出吗? 您提到第二个包含是使用指令(@include)的。然后在第一个输出结果中,您提到使用了指令(@include),但在第二个输出结果中,您也说它来自第二个包含(而根据您之前的解释,第二个包含是@ include)。 - stack247
41
如果有人对这个答案感到困惑, <jsp:include> 是动态的(JspRuntimeLibrary),而 <%@ include> 是静态的(out.write)。请注意,我已按要求进行了翻译,不包括任何额外解释,并尽力使结果通俗易懂,同时保持原意不变。 - eis
<%@include中的@eis是静态的(out.write),您是否指的是write中的任何内容,例如从请求中读取的EL将是动态还是静态?请问您能帮我吗?谢谢。或者它将被视为字符串${someVar} - shareef
1
@eis 是对的,回答中不太清楚是什么! - schlingel
2
这个答案在源代码解释方面非常好!!!我可以使用<%@include来实现全局变量共享,使用<jsp:include来单独处理JSP作用域变量而不会出现命名冲突问题。对于纯文本输出,两者是相同的。但对于变量作用域的使用,它们是非常不同的。 - Eddy

64

两种方式有很大的区别。正如之前所提到的,<%@ include是静态包含,<jsp:include是动态包含。如果你熟悉这些术语,可以把它看作宏和函数调用之间的区别。另一种说法是,静态包含就像是将被包含文件(“代码”)的完全内容复制粘贴到<% @ include 语句所在的位置一样(这正是JSP编译器将要做的事情)。

动态包含将使用请求分派器发出请求,执行指定的页面,然后在调用页面输出中包含该页面的输出,替换<jsp:include语句的位置。

这里的主要区别在于使用动态包含时包含的页面将在其自己的pageContext中执行。因为它是一个请求,所以可以像发送任何其他请求参数一样发送参数到该页面。相反,静态包含只是在调用页面的上下文中执行的一段代码。如果多次静态包含同一文件,则该文件中的代码将存在于调用页面的多个位置,因此类似于这样的东西:

<%
int i = 0;
%>

会生成编译错误(因为不能声明同一变量超过一次)。


这种答案是SO真正的礼物,为别人节省了几个小时,如果不是更多。 - Eagle_Eye

38

jGuru:

<%@include file="abc.jsp"%>指令类似于C语言中的"#include",它将包含文件的文本内容插入到当前JSP文件中,并将其编译为一个整体。被包含的文件可以是任何类型(包括HTML或文本)。

<jsp:include page="abc.jsp">标签则将被包含的文件作为一个独立的JSP文件进行编译,并在编译后的JSP文件中嵌入对它的调用。

一些JSP引擎支持非标准标签<!--#include file="data.inc"-->(NCSA-或.shtml风格)和<%@ vinclude="data.inc" %>(JRun风格),但这些标签没有在JSP规范中定义,因此不能保证可靠性。

更多信息请参见JSP FAQ中的相关问题。


31

1) 何时使用include指令?

为了防止在Web应用的多个JSP中重复编写相同的输出逻辑,使用包含机制,即使用包含指令促进表现逻辑的可重用性。

  <%@ include file="abc.jsp" %>
当jsp引擎收到上述指令时,它会检索abc.jsp的源代码并将其内嵌在当前jsp中。复制后对当前页面执行翻译。
简单地说,这是静态指令给jsp引擎,即“abc.jsp”的整个源代码复制到当前页面中。
2)何时使用include action?
include标签不会将所包含页面的源代码包含在当前页面中,而是将所包含页面在运行时生成的输出包含在当前页面响应中。
include标签的功能类似于servlet编程中请求分发器的包含机制。
include标签是jsp引擎的运行时指令,即从当前页面对“abc.jsp”进行方法调用,而不是将整个代码复制到当前页面。

1
很好的解释! 在翻译时(静态) 指令<%@ include file="file.jsp" %> 或 <jsp:directive.include file="file.jsp" />在运行时(动态)<jsp:include page="file.jsp" /> - Joe

2

Java Revisited

  1. 使用include指令包含的资源在JSP翻译期间加载,而使用include动作包含的资源在请求期间加载。
  2. 对于include指令,除非重新编译JSP文件,在包含的资源上进行任何更改都不会被显示。而在include动作中,下一个请求将显示包含资源中的任何更改。
  3. Include指令是静态导入,而Include动作是动态导入。
  4. Include指令使用文件属性指定要包含的资源,而Include动作使用页面属性实现相同的目的。

1

其中一个是静态导入(<%=@ include...>),另一个是动态导入(jsp:include)。这将影响您必须为所包含的文件指定的路径,例如。在Google上进行一些研究,您会了解更多信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接