Java 与<;jsp:include>;和<;@包括>;?动态包含和";“友好集装箱”;

Java 与<;jsp:include>;和<;@包括>;?动态包含和";“友好集装箱”;,java,jsp,servlets,include,jspinclude,Java,Jsp,Servlets,Include,Jspinclude,关于堆栈溢出,我们进行了很好的讨论,发现了它们之间的差异。粗略地说,是动态的,而是静态的。然而,我有一些问题 1。st问题 假设我使用包含header.jsp文件。它的运行方式如下:容器编译我的JSP文件,并在运行时调用header.JSP,它也会被编译。所以现在它使用它的内容作为对我的JSP文件的响应(并将其组合)。但它是如何动态的呢?如果我更改header.jsp会发生什么?因为它已经被编译过,所以不会看到任何更改。因此,是否每次都编译header.jsp,以保持其动态行为?或者有不同的方法

关于堆栈溢出,我们进行了很好的讨论,发现了它们之间的差异。粗略地说,
是动态的,而
是静态的。然而,我有一些问题

1。st问题

假设我使用
包含header.jsp文件。它的运行方式如下:容器编译我的JSP文件,并在运行时调用header.JSP,它也会被编译。所以现在它使用它的内容作为对我的JSP文件的响应(并将其组合)。但它是如何动态的呢?如果我更改header.jsp会发生什么?因为它已经被编译过,所以不会看到任何更改。因此,
是否每次都编译header.jsp,以保持其动态行为?或者有不同的方法“告诉”容器重新编译它

2。第二个问题

无论第一个问题的答案是什么,我都知道它是动态的,不管它是如何做到的。嗯,直到我从Head First JSP和Servlet中看到这张图片

这是否意味着即使是
也可以是动态的?如果我在Tomcat5(友好容器)中制作应用程序,为什么我会关心其他容器(旧版本)是否友好?我的意思是,我会使用一个容器并坚持使用它,而不是在其他容器中移动我的应用程序,对吗?那么,为什么我不总是使用
,让容器“处理”包含文件中的任何更改,而且使用RequestDispatcher不会对每个请求的性能产生影响(比如
指令是静态的,因为它接受包含文件的内容并简单地“转储”它)这是在翻译时完成的,因此内容成为父JSP的一部分,就像您自己在父JSP中编写的一样

操作是动态的,因为您“调用它”通过向它发送请求,它可以生成一个包含在父JSP输出中的响应。使其动态的是,您可以使用
子元素向它发送参数。因此,基本上,它不像在页面中转储某些内容,而是像一个可以使用参数调用的函数。因此它不仅包含内容,还包含使用模板生成的动态内容,您可以在不同时刻使用各种参数调用该模板

至于你的第二个问题,这与
指令或
操作本身无关,这就是服务器的工作方式(我觉得他们称之为“友好的容器”很愚蠢,但我想,这些书尽量做到友好).Tomcat实现者决定,他们可以让它检测编译时包含的页面何时发生更改,然后重新编译包含该页面的JSP,但其他servlet容器可能没有。规范没有指示实现者处理此问题,因此该行为不可移植到其他servlet容器


如果您想利用这一事实,这是您的选择,假设您在所有环境中运行同一台服务器,并且您可以保证这一事实不会改变,这一声明在开发环境中可能有效,或者如果您想玩东西,但在运行面向用户的p的专业设置中很可能无效生产代码,其中使用限制可移植性的专有内容是一种令人不快的做法。

谢谢Bogdan!所以让我澄清一下。底线是
都可以检测到包含的文件已更改。这样,容器将重新编译包含的文件,所以下次用户请求某些内容时,它将得到la测试更新的文件。我应该始终选择
,因为它只调用一次,而
每次用户请求某个内容时都会调用它。除非我想使用参数创建不同的内容(动态)每次-然后我选择
。我做对了吗?还有一件事,如果你知道的话。查看我发送的图片,它说只有较新的容器才能检测到
中包含的文件是否已更改。但是
呢?容器是否注意到每个容器中
的更改,还是只注意到较新容器中的更改?[…]
都可以检测到包含的文件已更改。不!操作和指令无法做到这一点。上图所示的是,服务器可以注意到包含的文件已更改,并且可以选择重建和重新编译使用它的代码。JSP规范没有说明服务器需要这样做。某些服务器实现之所以选择这样做,是因为它可能是人们为了方便开发而想要的功能,例如。但您不应该期望所有服务器都这样做。它不能在不同的服务器之间移植。