使用JSP include指令包含文件,使用JSP include操作和使用JSP标记文件之间有什么区别?


155

似乎有两种使用JSP进行模板制作的方法。包括具有以下语句之一的文件

<%@ include file="foo.html" %>
<jsp:include page="foo.html" />

或使用JSP标记文件

// Save this as mytag.tag
<%@ tag description="Description" pageEncoding="UTF-8"%>
<html>
<head>
</head>
<body>
    <jsp:doBody/>
</body>
</html>

并在另一个JSP页面中使用

<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:mytag>
    <h1>Hello World</h1>
</t:mytag>

那么我应该使用哪种方法呢?现在是不推荐使用的一种,还是它们既有效又涵盖了不同的用例?

编辑

使用此标记文件与使用包含文件不一样吗?

// Save this as product.tag
<%@ tag description="Product templage" pageEncoding="UTF-8"%>
<%@ tag import="com.myapp.Product" %>
<%@ attribute name="product" required="true" type="com.myapp.Product"%>

Product name: ${product.name} <br/>
Quantity: ${product.quantity} <br/>

并在另一个JSP上调用它

<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:product>
    <c:forEach items="${cart.products}" var="product">
        <t:product product="${product}"/>
    </c:forEach>
</t:product>

在我看来,这与使用include并将参数传递给它完全相同。标记文件和包含的文件一样吗?

Answers:


293

JSP语法元素概述

首先,为了使事情更清楚,这是JSP语法元素的简短概述:

  • 指令:这些指令整体上传达有关JSP页面的信息。
  • 脚本元素:这些是Java编码元素,例如声明,表达式,scriptlet和注释。
  • 对象范围:JSP对象可以显式或隐式创建,并且可以在给定范围内访问,例如,可以从JSP页面或会话中的任何位置访问。
  • 操作:这些操作创建对象或影响JSP响应中的输出流(或同时影响两者)。

JSP如何包含内容

有几种重用JSP文件中内容的机制。

以下将在JSP中包含内容的4种机制可以归类为直接重用:(
对于引用“ Head First Servlets and JSP”的前3种机制)

1)include 指令

<%@ include file="header.html" %>

静态在转换时将文件属性值中的内容添加到当前页面。该指令最初用于静态布局模板,例如HTML标头。

2)<jsp:include> 标准动作

<jsp:include page="header.jsp" />

动态在请求时将内容从页面属性的值添加到当前页面。旨在用于来自JSP的动态内容。

3)<c:import>JSTL标签:

<c:import url=”http://www.example.com/foo/bar.html” />

动态在请求时,将URL属性值中的内容添加到当前页面。它的工作原理与相似 <jsp:include>,但功能更强大,更灵活:与其他两个包含项不同,<c:import> URL可以来自Web Container外部

4)前奏和尾声:

静态的:前奏和尾声只能应用于页面的开头和结尾
您可以隐含包括序曲(也称为头)和音韵尾 一组JSP页面(也称为页脚)加入 <include-prelude><include-coda>一个内分别元素<jsp-property-group>在Web应用程序中元素的web.xml部署描述符。在此处了解更多信息:
在JSP的开头和结尾配置隐式包含
定义隐式包含


标记文件是内容重用的间接方法,是封装可重用内容的方法。一个标签文件是包含的JSP代码片段是可重复使用的源文件自定义标签

包含文件和标记文件的目的不同。

标记文件(JSP 2.0引入的一个概念)是创建自定义标记的选项之一。这是构建自定义标签的更快,更轻松的方法。 定制标记(也称为标记扩展)是JSP元素,允许将其他Java组件提供的定制逻辑和输出插入JSP页面。通过自定义标签提供的逻辑由称为标签处理程序的Java对象实现。

可以由自定义标签执行的任务的一些示例包括对隐式对象进行操作,处理表单,访问数据库和其他企业服务(例如电子邮件和目录)以及实现流控制。


关于您的编辑

也许在您的示例中(在您的Edit中),使用直接包含和标记文件之间没有区别。但是自定义标签具有丰富的功能。他们能

  • 通过调用页面传递的属性进行定制。

  • 将变量传递回调用页面。

  • 访问JSP页面可用的所有对象。

  • 互相交流。您可以创建和初始化JavaBeans组件,在一个标签中创建引用该bean的公共EL变量,然后在另一个标签中使用该bean。

  • 相互嵌套,并通过私有变量进行通信。

另请阅读“ Pro JSP 2”:了解JSP自定义标记


有用的阅读。


结论

为每个任务使用正确的工具。


使用标记文件作为创建自定义标记的快速简便方法,可以帮助您封装可重复使用的内容

至于JSP中的包含内容(从此处引用):

  • 如果文件更改很少,请使用include指令。这是最快的机制。如果您的容器没有自动检测到更改,则可以通过删除主页类文件来强制更改生效。
  • 仅在经常更改的内容上使用include操作,如果要在请求主页之前无法确定要包含的页面,则应使用include操作

但是<jsp:include>与使用标记文件不同吗?我看不出有什么区别...您可以将变量传递给<jsp:include>包含的文件,就像可以将变量传递给标记文件一样。两种方法都可以让您重复使用内容,它们似乎做的完全一样。除了名字外,它们之间还有其他区别吗?
sonicboom

@sonicboom更新了我的答案
informatik01

1
@ informatik01非常好的答案,我感谢它的深度,很好的格式设置和非常方便的4种机制列表。
罗素·席尔瓦

1
<jsp:include>优于<* @ include url ..>的优点是什么?
Krsna Chaitanya 2014年

@KrsnaChaitanya注意:您*在include指令中输入错误(星号)。<jsp:include>是标准的include 动作<%@ include file="" %>是include 指令。阅读最后一节(在灰色框中),概述了优点(即选择一个或另一个时的建议)。另请查看本文以获取详细说明。希望这可以帮助。
informatik01

21

可能重复的问题

<@include>-指令标记指示JSP编译器在创建生成的Servlet代码之前将包含文件的内容合并到JSP中。这等效于将包含页面中的文本剪切并粘贴到JSP中。

  • 在运行时仅执行一个servlet。
  • 可以在包含的页面中访问在父页面中声明的Scriptlet变量(请记住,它们是同一页面)。
  • 包含的页面不需要能够被编译为独立的JSP。它可以是代码片段或纯文本。包含的页面永远不会被编译为独立页面。尽管.jspf已成为常规使用的扩展名,但包含的页面也可以具有任何扩展名。
  • 旧容器的一个缺点是,在更新父页面之前,对包含页面的更改可能不会生效。Tomcat的最新版本将检查包含页面是否有更新,如果更新了父页面,则将强制重新编译它们。
  • 另一个缺点是,由于代码直接内联到生成的servlet的服务方法中,因此该方法可能会变得很大。如果超过64 KB,则您的JSP编译可能会失败。

<jsp:include> -另一方面,JSP Action标记指示容器暂停该页面的执行,运行包含的页面,并将该页面的输出合并到该页面的输出中。

  • 每个包含的页面在运行时都作为单独的servlet执行。
  • 可以在运行时有条件地包含页面。这对于模板化包含对象构建页面的框架通常很有用。父页面可以根据某些运行时条件确定要包括的页面。
  • scriptlet变量的值需要显式传递到包含页面。
  • 包含的页面必须能够独立运行。
  • 由于在生成的Servlet类中超过了最大方法大小,因此您不太可能遇到编译错误。

根据您的需要,您可以使用<@include><jsp:include>


1
您的意思是像您在问题中显示的那样<t:mytag><h1>Hello World</h1></t:mytag>吗?这不是包含项,而是标记(如<jsp:useBean><c:if>)的常规用法。
Uooo

那么,使用标记文件和包含文件之间有什么区别(似乎可以使用标记文件在页面中包含内容)?
sonicboom

9

<jsp:include />over的主要优点<%@ include >是:

<jsp:include /> 允许传递参数

<jsp:include page="inclusion.jsp">
    <jsp:param name="menu" value="objectValue"/>
</jsp:include>

这是不可能的 <%@include file="somefile.jsp" %>


标签文件呢,我知道inlcude是如何工作的。我想知道标记文件如何与包含相关,因为它们似乎提供了相同的功能。使用标记文件和使用包含文件之间有什么区别?
sonicboom

怎么样<%@include file="somefile.jsp?menu=value" %>?也有限制吗?
Roshana Pitigala

5

所有三个模板选项- <%@include><jsp:include>并且<%@tag>是有效的,并且所有三个覆盖不同的使用情况。

使用<@include>,JSP解析器在编译之前将包含文件的内容内联到JSP中(类似于C#include)。您可以将此选项与简单的静态内容一起使用:例如,如果要在Web应用程序的每个页面中包含页眉,页脚或导航元素。包含的内容成为已编译JSP的一部分,并且在运行时没有任何额外成本。

<jsp:include>(和JSTL <c:import>相似,甚至更强大)最适合动态内容。当您需要包含来自本地或远程另一个URL的内容时,请使用它们。当您包含的资源本身是动态的时;或当包含的内容使用与包含的页面冲突的变量或bean定义时。<c:import>还允许您将包含的文本存储在变量中,您可以进一步对其进行操作或重用。这两种方法都会为分派产生额外的运行时成本:这是最小的,但是您需要知道动态包含不是“免费的”。

当您要创建可重用的用户界面组件时,请使用标记文件。例如,如果您有一个窗口小部件列表,并且想要遍历窗口小部件并显示每个窗口小部件的属性(在表格或表单中),则可以创建一个标签。标签可以使用<%@tag attribute>这些参数可以是强制性的或可选的-有点像方法参数。

标记文件是一种更简单的基于JSP的标记库编写机制,您必须使用Java代码编写(JSP 2.0之前的版本)。当标记中有很多渲染工作时,编写JSP标记文件会更加干净:您无需像使用Java编写标记那样就必须混合Java和HTML代码。


1

根据: Java再探

  1. include指令包含的资源在jsp转换期间加载,而include动作包含的资源在请求期间加载。

  2. 在include指令的情况下,对包含资源的任何更改将不可见,直到再次编译jsp文件。在包含动作的情况下,包含资源的任何更改将在下一个请求中可见。

  3. include指令是静态导入,而include动作是动态导入。

  4. include指令使用文件属性来指定要包含的资源,而include动作则使用page属性来达到相同的目的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.