JSP中主要包含三大指令,分别是page,include,taglib。本篇主要提及include指令。

include指令使用格式:<%@ include file="文件的绝对路径或相对路径"%>

file属性:指定被包含的文件,该属性不支持任何表达式,也不允许通过如下的方式来传递参数。

<%@ include file="welcome.jsp?name=Tom"%>下面用法将会抛出异常,也是不允许的:

<% String path="login.jsp";%>

<%@ include file="<%=path%>"%>

如果该属性值以”/“开头,那么指定的是一个绝对路径,将在当前应用的根目录下查找文件;如果是以文件名称或文件夹名开头,那么指定的是一个相对路径,将在当前页面的目录下查找文件。

JSP中常用的动作标识有<jsp:include>、<jsp:forward>、<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>、<jsp:fallback>、<jsp:pugin>。本篇主要提及<jsp:include>动作标识。

<jsp:include>动作标识使用格式:<jsp:include page="被包含文件的路径" flush="true|false"/>

或者向被包含的动态页面中传递参数:

<jsp:include page="被包含文件的路径" flush="true|false"><jsp:param name="参数名称" value="参数值"/></jsp:include>

page属性:和include指令的file属性一样。

flush属性:表示当输出缓冲区满时,是否清空缓冲区。该属性值为boolean类型,默认值为false,通常情况下设为true。

处理方式不同:使用include指令,被包含的文件的内容会原封不动地插入到包含页中使用该指令地位置,然后JSP编译器再对这个合成地文件进行编译最终编译成的文件只有一个。使用include动作标识,该标识被执行时,程序会将请求转发到(注意是转发而不是请求重定向)被包含的页面,并将执行结果输出到浏览器中,然后返回包含页继续执行后面的代码。服务器执行的是两个文件,JSP编译器会分别对这两个文件进行编译。注:]请求转发,存储在request对象中的信息会被保留并被带到目标页面中;请求重定向,重新生成一个request请求,将该请求重定向到指定的URL,所以事先存储在request对象中的信息都不存在了。

包含方式不同:include指令,静态包含,最终服务器执行的是将两个文件合成后由JSP编译器编译成的一个class文件,若改变被包含的文件,则主文件的代码就发生了改变,服务器会重新编译主文件。include动作标识,动态包含,通常用来包含那些经常需要改动的文件。服务器执行的是两个文件,被包含文件的改动不会影响到主文件,服务器不需要对主文件进行重新编译,只需要重新编译被包含的文件即可,而只有当<jsp:include>动作标识被执行时,使用该标识时,目标文件才会被编译。

约定不同:include指令的约定index.jsp文件的部分代码

1 <%@ page language="java" contentType="text/html; charset=UTF-8"%>
2 <%@ include file="top.jsp" %>

top.jsp文件的部分代码

1 <%@ page language="java" contentType="text/html; charset=GB2312"%>

访问index.jsp将会出现异常

<jsp:include>动作标识,无需遵循这样的约定,不会出现异常

1 <%@ page language="java" contentType="text/html; charset=GB2312"%>
2 <jsp:include page="top.jsp"/>

——————————————————————————————————————————————————————

关于include指令和include动作指令的介绍见JSP基本语法(三)

首先,我们来看一下include指令所包含的内容与当前页面是一个整体是什么意思。

我们在Tomcat安装目录下的webapps文件夹下新建一个文件夹includeTEST,在这里进行一些实验。

在includeTEST文件夹下新建一个include.jsp:

<%@ page language="java" import="java.util.*" contentType="text/html;charset=gb2312"%><html><head><title>include</title></head><body>现在是:<%@ include file="date.jsp" %></body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这个JSP页面中,我们用include指令静态包含了date.jsp,接下来我们就新建一个date.jsp放在和include.jsp相同的目录下/webapps/includeTEST/

date.jsp

<% Date date = new Date();
%><%=date.toString()
%>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

接下来启动Tomcat,打开浏览器输入

localhost:8080/includeTEST/include.jsp
  • 1
  • 2

能够正常显示出当前时间。然后我们到Tomcat安装目录下的

\work\Catalina\localhost\includeTESTorg\apache\jsp
  • 1
  • 2

中去查找include.jsp页面生成的对应的java文件,事实上我们会在这个目录下找到inlucde_jsp.java以及include_jsp.class,没有date_jsp.java相关的文件,说明include.jsp页面包括静态包含的date.jsp,一起只生成了一个文件,include_jsp.java截取如下:

      out.write("\r\n");out.write("\r\n");out.write("<html>\r\n");out.write("  <head><title>JSP-welcome</title></head>\r\n");out.write("  <body>\r\n");out.write("    现在是:");Date date = new Date();out.write("\r\n");out.write("\r\n");out.print(date.toString()   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

我们发现,在该include_jsp.java文件中,new了一个Date对象,然后进行打印输出,也就是直接将date.jsp中的内容合进来,生成了同一个文件。

作为对比,我们同样在includeTEST/下新建一个includeAction.jsp,我们这次试用jsp的include动作指令来包含date.jsp:

<%@ page language="java" import="java.util.*" contentType="text/html;charset=gb2312"%><html><head><title>includeAction</title></head><body>现在是:<jsp:include page="date.jsp"/></body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

此时,我们打开浏览器输入

localhost:8080/includeTEST/includeAction.jsp
  • 1
  • 2

出现了错误!

错误信息:

org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: 2 in the jsp file: /date.jsp
Date cannot be resolved to a type
1: <%
2:   Date date = new Date();
3: %>
4:
5: <%=
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

错误原因很简单,Date不能识别!但是使用<%@ include file="date.jsp" %>时可以识别,为什么此处<jsp:include page="date.jsp"/>就不能识别?!

原因就在于那句话:include标签会把包含的部分和当前页面生成同一个整体!于是Date就被头部的<%@ page language="java" import="java.util.*" contentType="text/html;charset=gb2312"%>中的import=”java.util.*”引进来了。但是使用<jsp:include page="date.jsp"/>生成的是两个单独的实体,于是在date.jsp这个独立的实体中,Date将无法识别!

这时候我们再次打开以下目录:

\work\Catalina\localhost\includeTESTorg\apache\jsp
  • 1
  • 2

会发现,当前目录下生成了

在这里我们看到了date_jsp.java,includeAction_jsp.java以及includeAction_jsp.class文件。生成了includeAction对应的class文件,说明includeAction.jsp页面可以正常编译执行。再次说明,includeAction.jsp和date.jsp是两个单独的实体!同时,由于includeAction.jsp能够生成class文件,也说明了date_jsp.java的编译执行起码是在includeAction执行之后才进行的,实际上是执行到

    现在是:<jsp:include page="date.jsp"/>
  • 1
  • 2

对应的语句的时候,date.jsp才第一次被请求。但是编译出错。

接下来我们做以下修改,我们把date.jsp做以下修改并另存为date1.jap:

<%@ page language="java" import="java.util.*" contentType="text/html;charset=gb2312"%><% Date date = new Date();
%><%=date.toString()
%>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

再次在浏览器输入

localhost:8080/includeTEST/includeAction.jsp
  • 1
  • 2

此时,时间可以打印出来了!关于中文乱码问题我们暂时不管。

再次进入

\work\Catalina\localhost\includeTESTorg\apache\jsp
  • 1
  • 2

此时生成了对应的date1_jsp.java以及date1_jsp.class文件:

最后我们用打开includeAction_jsp.java,部分代码如下:

      out.write("\r\n");out.write("\r\n");out.write("<html>\r\n");out.write("  <head><title>includeAction</title></head>\r\n");out.write("  <body>\r\n");out.write("    现在是:");org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "date1.jsp", out, false);out.write("\r\n");out.write("  </body>\r\n");out.write("</html>");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这里我们可以清楚地看到,对date1.jsp的include是通过请求的方式进行的!

通过这个实验我们可以看到include指令和include动作指令的区别。更多细节的差异,可以类似地通过更多的实验来探索验证。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

include指令和include动作都能实现将外部文档包含到JSP文档中的功能,名称也很相似,非常容易混淆。include指令和include动作到底有什么分别,哪一种方式会更好呢?
1.include指令
    include可以在JSP页面转换成Servlet之前,将JSP代码插入其中。它的主要优点是功能强大,所包含的代码可以含有总体上影响主页面的JSP构造,比如属性、方法的定义和文档类型的设定。它的缺点是难于维护只要被包含的页面发生更改,就得更改主页面,这是因为主页面不会自动地查看被包含的页面是否发生更改。
include指令的语法格式如下
    <%@ include file="Relative Url"%>

2.include动作
  jsp:include动作是在主页面被请求时,将次级页面的输出包含进来。尽管被包含的页面的输出中不能含有JSP,但这些页面可以是其他资源所产生的结果。服务器按照正常的方式对指向被包含资源的URL进行解释,因而这个URL可以是Servlet或JSP页面。服务器以通常的方式运行被包含的页面,将产生的输出放到主页面中,这种方式与RequestDispatcher类的include方法一致。它的优点是在被包含的页面发生更改时,无须对主页面做出修改。它的缺点是所包含的是次级页面的输出,而非次级页面的实际代码,所以在被包含的页面中不能使用任何有可能在整体上影响主页面的JSP构造。
  jsp:include动作的完整语法如下
 <jsp:include page="Relative path to resource" flush="true">
  其中jsp:include之间不能有空格,page属性指定被包含的页面,这个属性是必需的,是指向某种资源的相对URL。如果这个相对URL不是以/开头,则将其解释为相对于主页面的路径;如果是以/开头,是这个URL被解释为相对于当前WEB应用的根目录,而不是服务器的根目录,这是因为该URL是由服务器来解释的,不是由用户的浏览器来解释的。像下面这行代码,是由用户的浏览器进行解释的,因此会按照相对于服务器的根目录进行解释。
  flush属性是一个可选的次级属性,默认值为false,它指定在将页面包含进来之前是否应该清空主页面的输出流。
   注意:在JSP1.1中,flush是必需的属性,而且聚会只能是true。
3.两者的区别和比较
   jsp:include动作和include指令之间的根本性的不同在于它们被调用的时间。jsp:include动作在请求期间被激活,而include指令在页面转换期间被激活。
   两者之间的差异决定着它们在使用上的区别。使用include指令的页面要比使用jsp:include动作的页面难于维护。前面已经说过,使用JSP指令,如果包含的JSP页面发生变化,那么用到这个页面的所有页面都需要手动更新。在JSP服务器的相关规范中并没要求能够检测出包含的文件什么时候发生改变,实际上大多数服务器页都有去实现这种机制。这样就会导致十分严重的维护问题,需要记住所有包含某一个页面的其他页面,或者重新编译所有的页面,以使更改能够生效。在这点上,jsp:include就体现出了十分巨大的优势,它在每次请求时重新把资源包含进来。在实现文件包含上,应该尽可能地使用jsp:include动作。
   jsp:include动作直比于include指令在维护上有着明显优势,而include指令仍然能够得以存在,自然在其他方面有特殊的优势。这个优势就是include指令的功能更强大,执行速度也稍快。include指令允许所包含的文件中含有影响主页面的JSP代码,比如响应报送的设置和属性方法的定义。以下表格就是两种包含方式的对比:

include指令

jsp:include动作

语法格式

<%@ include file=”..”%>

<jsp:include page=”..”>

发生作用的时间

页面转换期间

请求期间

包含的内容

文件的实际内容

页面的输出

转换成的Servlet

主页面和包含页面转换为一个Servlet

主页面和包含页面转换为独立的Servlet

影响主页面

可以

不可以

include指令

jsp:include动作

发生更改时是否需要显式更改主页面

需要

不需要

编译时间

较慢-资源必须被解析

较快

执行时间

稍快

较慢-每次资源必须被解析

灵活性

较差-页面名称固定

更好-页面可以动态指定

了解到jsp:include动作和include指令各自的功能和区别,在使用时,就可以通过考虑各方面的因素,来决定使用哪一种方式。尽管各自都有一定的优缺点,在实际使用中,还是应优先考虑使用jsp:include动作,这是因为它在代码维护上的优势远胜过其在功能上的不足。

浅谈JSP中include指令与include动作标识的区别相关推荐

  1. 浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别

    浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别 标签: caffe深度学习CaffeNet 2016-11-02 16:10 1203人阅读 评论(1) ...

  2. 浅谈Java中的Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  3. Java基础学习总结(29)——浅谈Java中的Set、List、Map的区别

    Java中的Set,List,Map的区别,对JAVA的集合的理解是相对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操作数目不固定的一 ...

  4. 浅谈Python中的type()、dtype()、astype()的区别

    函数 说明 type() 返回数据结构类型(list.dict.numpy.ndarray 等) dtype() 返回数据元素的数据类型(int.float等)备注:1.由于 list.dict 等可 ...

  5. 浅谈PHP中静态方法调用和实例化类调用的区别

    1.观点一: 静态方法只有一个,无论你调用多少次,都是共用的,是没有对象的概念,因此不能在静态方法里面使用$this调用,如果非得调用的话,只能实例化自身类 实例化不一样,每一个实例化是一个对象,拥有 ...

  6. JSP中的include指令和include动作的区别

    我们都知道在jsp中include有两种形式,分别是Include指令:<%@ include file=""%>和include动作:<jsp:include ...

  7. vue 给checkbox 赋值_浅谈vue中关于checkbox数据绑定v-model指令的个人理解

    vue.js为开发者提供了很多便利的指令,其中v-model用于表单的数据绑定很常见, 下面是最常见的例子: {{msg}} js里data初始化数据 new Vue({ el: "#myA ...

  8. linux中whoami命令的作用是,浅谈linux中的whoami与 who指令

    浅谈linux中的whoami与 who指令 whoami 功能说明: 显示用户名称 语法: whoami 补充说明: 显示自身的用户名称,本指令相当于执行  id -un 指令 whoami 与 w ...

  9. 实现Linux的whoami命令,浅谈linux中的whoami与 who指令

    whoami 功能说明: 显示用户名称 语法: whoami 补充说明: 显示自身的用户名称,本指令相当于执行  id -un 指令 whoami 与 who am i的区别 who这个命令重点在用来 ...

最新文章

  1. mugen4g补丁如何使用_CAD如何去除教育版戳记?
  2. Android开发笔记(一百四十四)高仿支付宝的头部伸缩动画
  3. 操作数据库pymysql
  4. Tensorflow默认占满全部GPU的全部资源
  5. POJ 2480 Longge#39;s problem 积性函数
  6. AIR移动平台打开图片文件
  7. 程序员课外拓展004:Photoshop CC 2018详细图文安装教程
  8. 第二届(2017)中国IT武林大会暨2017年度中国IT年度人物颁奖盛典
  9. 现代软件工程 -- 第一周 -- 介绍自己
  10. 21-selenium之options模块
  11. 计算机基础知识初中生学习,初中生具备了学习电脑的能力吗?
  12. TypeError:Cannot read property 'bind' of underfined(React)
  13. css固定图片大小 vue_css3 实现图片等比例放大与缩小
  14. 行业:美团将在快手开放平台上线美团小程序
  15. 修改相关properties配置文件后,配置正确,没有生效。
  16. 微信小程序的图形验证码实现
  17. 如何找到IEEE里面的论文模板
  18. MMA-Mathematica初步了解和使用-MMA
  19. 一篇文章讲清什么是零知识证明
  20. SSH框架搭建整合详细步骤及运行流程

热门文章

  1. matlab写音符,用matlab演奏《青花瓷》
  2. java乐器_java类的多态编程。 (1)乐器(Instrument)分为:钢琴(Piano)、小提琴(Vio...
  3. 关于不过洋节的通知_关于不过洋节的作文3篇_优秀作文
  4. 郭靖黄蓉之死—附椅天剑屠龙刀的由来...
  5. 电脑上如何转换视频格式?万兴优转-适配多种设备及批量高速转换
  6. angularjs定时任务的设置与清除
  7. java sha256加密后base64编码
  8. Oralce 随手笔记(二)
  9. 蜗牛星际USB不识别
  10. 8CB8CCD14EB87A3614FF883829721920