`
113.com
  • 浏览: 76560 次
  • 来自: 广州
社区版块
存档分类
最新评论

include与jsp:include区别

    博客分类:
  • JSP
 
阅读更多

         我们都知道在jsp中include有两种形式,分别是
<%@ include file=” ”%>
<jsp:include page=” ” flush=”true”/>

前者是指令元素、后者是行为元素。具体它们将在何处用?如何用及它们有什么区别?这应该是很多人看到它都会想到的问题。下面一起来看看吧。

通常当应用程序中所有的页面的某些部分(例如标题、页脚和导航栏)都相同的时候,我们就可以考虑用include。具体在哪些时候用<%@ include file=” ”%>,哪些时候用<jsp:include page=” ” flush=”true”/>.这种形式。首先要明白的是它们之间的区别。只有了解了它们用法的不同才理解该在何时去用以及如何选择。
<%@ include file=” ”%>,jsp的include指令元素读入指定页面的内容。并把这些内容和原来的页面融合到一起。(这个过程是在翻译阶段:也就是jsp被转化成servlet的阶段进行的。)

这里对翻译阶段进行一下说明:我们知道,jsp页面不能原封不动地被传送给浏览器,所有的jsp元素都必须首先由服务器进行处理。这是通过将jsp页面转达化成servlet,然后执行这个servlet来完成的。服务器需要一个jsp容器来处理jsp页面。jsp容器通常以servlet的形式来实现,这个servlet经过配置,可以处理对jsp页面的所有请求。

Jsp容器负责将jsp页面转化成servlet(称为jsp页面实现类?JSP Page implementation class),并编译这个servlet。这两步就构成了翻译阶段.

由此我们就会知道:jsp页面是把include指令元素所指定的页面的实际内容(也就是代码段)加入到引入它的jsp页面中,合成一个文件后被jsp容器将它转化成servlet。可以看到这时会产生一个临时class文件和一个java文件。下面举个例子。

服务器用tomcat,引入页面的jsp文件叫test.jsp。被引入的页面叫date.jsp.这个jsp文件里存放的是一个有关时间的jsp代码,当前的上下文根设为test
//======date.jsp的源文件=====//

<%@ page language=”java” c%> 
<% 
java.util.Date date=new java.util.Date(); 
String date_cn =""; 
String dateStr = ""; 
switch(date.getDay()) 
{ 
case 0:date_cn ="日"; break; 
case 1:date_cn ="一"; break; 
case 2:date_cn ="二"; break; 
case 3:date_cn ="三"; break; 
case 4:date_cn ="四"; break; 
case 5:date_cn ="五"; break; 
case 6:date_cn ="六"; break; 
} 
dateStr = (1900+date.getYear()) + "年" + (date.getMonth()+1) + "月" + date.getDate() + "日(星期" + date_cn + ")"; 
%> 
document.write("<%=dateStr%>"); 
//======以下是test.jsp的源文件=============// 
<%@ page language=”java” contentType=”text/html;charset=gb2312”%> 
<html> 
<head> 
<title>include的两种用法</title> 
<jsp:include page=”date.jsp” flush=”true”/> 
<%--@ include file=”date.jsp” %--> 
//我们在这里用include的两种不同形式来引入date.jsp这个文件. 
<head> 
<body> 
<table><tr><td> 
有关jsp中include的两种用法.敬请关注。 
</td></tr></table> 
</body> 
</html> 

 

在test.jsp 文件中,我们只输出了一行文本“ 有关jsp中include的两种用法.敬请关注。”,现在让我们先用<%@ include file=”date.jsp” %>这种形式引入date.jsp这个文件。你想会出现什么问题了吗?此时出现了错误提示:
HTTP Status 500 ?
org.apache.jasper.JasperException: /date.jsp(0,0) Page directive: can't have multiple occurrences of contentType
以下还有一堆错误,但我们只要看这里就知道问题的所在了。状态码为http 500服务器内部错误。再看下面的提示。在date.jsp页面中不能指定多个contentType. 原因就在这里了。是因为在翻译阶段,date.jsp文件的代码被原封不动地加入到了test.jsp页面从而合成一个文件。合成后的文件中就会相同的:
<%@ page language=”java” contentType=”text/html;charset=gb2312”%>
这句代码。解决的办法是把date.jsp文件中的这句删掉。刷新后再请求test.jsp页面
请求test.jsp在页面显示如下
2003年12月10日 13:12:40
这时我们还不能发现什么。还是去查看tomcat下的临时文件吧。到那里去看看date.jsp文件的内容是否已被加入到了test.jsp文件中。
在目录下会看到test_jsp.java和test_jsp.class两个文件.
这里的java文件就是jsp容器将jsp转化成了servlet而得到的test_jsp.java这个文件。相对应的test_jsp.class这 个文件就是编译test_jsp.java这个servlet文件产生的类文件了。打开所产生的servlet文件(test_jsp.java),此时 我们会发现,在test.jsp 文件被转化成servlet文件时,在输出的<haed>之间加入了一些不是test.jsp页面里面的代码,新加入的内容就是 date.jsp里面的代码: 新加入了哪些内容或是否真的加入了新的内容请自己测试去看一下就会一目了然了.在这里不再详述.
以上就是我们用<%@ include file=”date.jsp”%>这种形式得到的结果.

下面我们换用<jsp:include page=”dae.jsp” flush=”true”/>也就是将
<%@ include file=”date.jsp”%>换成<jsp:include page=”dae.jsp” flush=”true”/>,然后请求test.jsp.
2003? ê 12??10?? 13:30:13
此时会在页面上看见.我们所引入date.jsp输出的日期中中文出现了乱码.什么原因?是因为include行为元素是在请求处理阶段执行的(此处要对 请求处理阶段进行说明一下,Jsp容器除了上面提到的负责将jsp页面转化成servlet外,还负责调用jsp页面实现类以处理每个请求并产生应答.这 个阶段我们就称为请求处理阶段.请求处理阶段仅执行类文件)。
所以在我们作include行为元素引入页面时,实际只是引用了date.jsp这个文件被转化并被编译后产生的servlet类文件.既如此, date.jsp就是作为一个单独的文件在执行后才被test.jsp文件运行时调用.由于date.jsp文件中没有指定字符编码.所以出现了乱码.解 决办法是在date.jsp文件中重新把刚才去掉的
<%@ page language=”java” contentType=”text/html;charset=gb2312”%>
这行语句加入后刷新重新运行.此时页面显示正确,并跟用include指令正常运行时一样.再查看tomcat下的临时文件会发现.此时多出了一个 date_jsp.java文件和一个date_jsp.class文件.这两个文件得来的方式跟test_jsp.java和 test_jsp.class文件得来的方式一样.再查看一下此时test_jsp.java文件的代码会发现.此时只新增加了一句代码:
JspRuntimeLibrary.include(request, response, "date.jsp", out, true);
它并没有把date.jsp文件的代码加入到test.jsp.只是在运行时引入了date.jsp页面执行后所产生的应答.这意味着我们可以指定任何能 够产生应答的Web资源,(例如一个servlet或一个jsp页面),只要这些资源所产生的类型和jsp页面产生的内容类型相同.JSP容器将通过一个 内部的函数调用来执行指定的资源.因此,这些被引入的资源可以帮助处理原来的请求,所以这些资源可以访问请求作用域内的所有对象.以及所有原来的请求参 数.
由于在主页面被请求时,这些页面还没有被引入到主页面中,所以你可以对page属性使用一个请求时属性值,以便根据运行时的情况来决定要引入哪一个页面.还可以添加一些将被引入的页面读取的请求参数.

<jsp:include page=”<%=pageSelectedAtRuntime%>” flush=”true” > 
<jsp:param name=”fitstParamer” value=”firstValue”> 
<jsp:param name=”lastParamer” value=”lastValue”> 
</jsp:include> 

 

如果修改了被引入的jsp页面,那么可以立刻使用该页面的最新版本,这是因为对待被引入的页面的方式与对待由浏览器直接调用的jsp页面的方式完全相同.即容器检测页面的变化,并自动进入翻译阶段,以得到页面的最新版本.
(注意,include行为元素同jsp其它元素一样,没有行为体时要以”/”结束.就像下面这样.
<jsp:include page=”<%=pageSelectedAtRuntime%>” flush=”true” />)

以下是对include 两种用法的区别
主要有两个方面的不同;

一:执行时间上:
<%@ include file=”relativeURI”%> 是在翻译阶段执行
<jsp:include page=”relativeURI” flush=”true” /> 在请求处理阶段执行.

二:引入内容的不同:
<%@ include file=”relativeURI”%>
引入静态文本(html,jsp),在JSP页面被转化成servlet之前和它融和到一起.
<jsp:include page=”relativeURI” flush=”true” />引入执行页面或servlet所生成的应答文本.
另外在两种用法中file和page属性都被解释为一个相对的URI.如果它以斜杠开头,那么它就是一个环境相关的路径.将根据赋给应用程序的URI的前缀进行解释,如果它不是以斜杠开头,那么就是页面相关的路径,就根据引入这个文件的页面所在的路径进行解释.

 

 


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


从一个需求说起(自己之前对WEB项目中的相对路径和绝对路径有一些了解)

需求是这样的,要在JSP中应用<jsp:include>标签引入一个公用的页面
引用
<jsp:include page="../templates/header.jsp"></jsp:include>

就是写类似上面的一段语句。

不过这段代码的要求是要在本项目中任意一个JSP文件中都管用的,
说白了就是在项目现有的任意一个页面中加入相同的这样一段代码,都能达到引入某个固定页面的效果。

所以这里不能用相对路径。原因我自己总结了两条:

1,没办法保证对页面的访问方式,是直接访问还是通过其它请求跳转访问,访问的URL不确定,相对路径达不到要求。

2,项目中的页面本身目录结构不可能都正好在一个文件夹中。

所以自然想到用绝对路径,所以开始我是这样写的
引用

<jsp:include page="<%=request.getContextPath()%>/templates/header.jsp"></jsp:include>


这么写,当时没多想,就是直接仿照引入其它图片CSS什么的写的。比如
Java代码 
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/xx.css"/>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/xx.css"/>

页面报错,之后想想,TOMCAT(我用的是TOMCAT)解析JSP时,对<jsp:include>的解析有别于其它。

Java代码 
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/xx.css"/>
只是按照基本规则简单的解析为几个输出语句:
out.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"");
out.print(request.getContextPath());
out.write("/css/xx.css\"/>\r\n");
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/xx.css"/>只是按照基本规则简单的解析为几个输出语句: out.write("<link rel=\"stylesheet\" type=\"text/css\" href=\""); out.print(request.getContextPath()); out.write("/css/xx.css\"/>\r\n");

而对<jsp:include>的解析却要特殊一些,它没有直接输出字符串的语句,而是这样的:
引用

<jsp:include page="../templates/header.jsp"></jsp:include>
被解析为:
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "../templates/header.jsp", out, false);


自己简单总结了下,JSP中对<jsp:include>标签的解析就是直接生成上面那样一条语句,而page属性的值直接作为方法的参数,也因为这个,所以page的值不能这样写page="<%=request.getContextPath()%>/templates/header.jsp"。之所以不能这样写(自己认为)也没什么道理需要讲,说白了就是JSP没这样的语法。

也就是说对于<jsp:include>标签的page属性的值,只能是一个写死的字符串。否则在JSP级别上就会有语法错误,结果是容器连对应的JAVA文件都没办法生成,更不要说真正用到的CLASS文件了。

综上,所以页面会报错。

那么这里怎么用绝对路径呢?或者说 org.apache.jasper.runtime.JspRuntimeLibrary.include方法是怎么用的?

GOOGLE了下 也没找到什么对自己有用的(自己看得懂的)东西。

又尝试了其它几种形式

Java代码 
<jsp:include page="/项目名/templates/header.jsp"></jsp:include>
解析为
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/项目名/templates/header.jsp", out, false);
<jsp:include page="/项目名/templates/header.jsp"></jsp:include>解析为org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/项目名/templates/header.jsp", out, false);

Java代码 
<jsp:include page="http://localhost:8080/项目名/templates/header.jsp"></jsp:include>
解析为
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "http://localhost:8080/项目名/templates/header.jsp", out, false);
<jsp:include page="http://localhost:8080/项目名/templates/header.jsp"></jsp:include>解析为org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "http://localhost:8080/项目名/templates/header.jsp", out, false);

以上2种尝试,对于标签的解析结果符合之前我的结论,JSP顺利的生成了最后的CLASS文件。
可是访问时继续报错。
"/项目名/templates/header.jsp”“http://localhost:8080/项目名/templates/header.jsp”
这两种路径就是WEB项目中绝对路径的用法。
而连生成的JAVA文件中,方法的参数也都已经成功把这2个参数带入了,可是仍报错。
显然org.apache.jasper.runtime.JspRuntimeLibrary.include方法对路径的解析与IE不同。


人多力量大,请经理来看看,在报错信息中发现了问题。


之前2中用法:
<jsp:include page=" /项目名/templates/header.jsp"></jsp:include>
报的错为
org.apache.jasper.JasperException: javax.servlet.ServletException: File &quot; /项目名/templates/header.jsp&quot; not found
提示找不到的页面就是参数给出的页面"/项目名/templates/header.jsp"
这个去掉开头的“/”后面的路径应该绝对没问题,除非这个“/”不代表服务器的根目录(服务器地址)


下面
<jsp:include page=" http://localhost:8080/项目名/templates/header.jsp">
报的错为
org.apache.jasper.JasperException: javax.servlet.ServletException: File &quot; /templates/http:/localhost:8080/项目名/templates/header.jsp&quot; not found

提示找不到的页面比参数在前面多出了一段 /templates/
就是说这里并没有因为参数以“http://”开头而给予"特殊待遇",只是把它当成了一段普通的字符串,同时因为不是以“/”开头的而被当成了相对路径处理,并在前面补充上了"/templates/"
那个如果是这样,这个 "/templates/"就应该是自身所在的位置,而按此推理,这个“/”代表了???

 


又实验了下

<jsp:include page=" ../templates/一个不存在的页面"></jsp:include>
报错为
org.apache.jasper.JasperException: javax.servlet.ServletException: File &quot; /templates/一个不存在的页面&quot; not found

 

结论


观察了下,想了想,知道了,原来我饶了一个大圈,问题其实很简单:

总结了下,JSP中<jsp:include>标签的应用:
1,支持<%= %>等动态的语法,特别是page属性的值,只能是一个写死的字符串(刚听说,其实也有自己本身的一些特殊语法,以后再学)
2,对于引入页面的路径问题,也可以常用"绝对路径"和"相对路径"两种应用方式。
绝对路径就是以“/”开头的路径,其它的包括以“http://”开头的都是相对路径,可应用“./”“../”等

相对路径 没什么好说的。强调一点,这里的相对路径也是相对于访问页面的URL的路径,本质上与页面文件在项目中的存储位置没直接关系,所以这里用相对路径时也存在由于访问URL不确定带来的问题(是不是这样呢?如文章开头说的,这里都是我自己的结论)。

主要是绝对路径的问题:
我们知道大部分情况下写在页面(不管静态还是动态)里并输出到IE中的路径都是由IE来解析的,以“/”开头的绝对路径 这个“/”代表的是服务器的根目录:比如访问URL为 http://localhost:8080/项目名/templates/template.jsp
那么“/”代表的就是 "http://localhost:8080/" 而并不带有项目名信息。

而<jsp:include>引入页面的过程,是在服务器运行向IE输出数据的过程中由JAVA程序调用执行,路径也当然由JAVA程序来解析,此时以"/"开头的绝对路径中的“/” 代表的已经是本项目的根目录了。
比如 URL为 http://localhost:8080/项目名/templates/template.jsp
那么“/”代表的就是 "http://localhost:8080/项目名/"。已经带有了项目名信息。

同时,也不用像引入JS CSS文件那样在路径前加上 <%=request.getContextPath()%> 来解决项目名本身修改的问题了。只需一个“/”就什么也不用管了。


如上所述:
需求需要的这段代码其实很简单

引用
<jsp:include page="/templates/header.jsp"></jsp:include>


需要被任意位置的页面引入的页面 存放在项目根目录下的templates目录下

 

 


问题补充:

多谢,特别是1楼说的第一点(1.jsp:include支持<%=%>语句。),使自己有动力学一学 jsp:include 中 <%=%>到底怎么用


做了个测试:

测试1:
Java代码 

<% String pageURL = "header.jsp"; %><%=pageURL%><jsp:include page= [color=red]"/templates/<%=pageURL%>" [/color]></jsp:include>
被解析成了这样一段JAVA代码
String pageURL = "header.jsp";
out.print(pageURL);
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, [color=red]"/templates/<%=pageURL%>" [/color], out, false);
<% String pageURL = "header.jsp"; %><%=pageURL%>

 <jsp:include page= [color=red]"/templates/<=pageURL%>" [/color]></jsp:include> 被解析成了这样一段JAVA代码 String pageURL = "header.jsp"; out.print(pageURL); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, [color=red]"/templates/<%=pageURL%>" [/color], out, false);

这个跟我之前说的一样, page="/templates/<%=pageURL%>" 引号中的值被当成了一个字符串作为对应方法的参数,而没有对 <%=%>有什么特殊的处理。


测试2:

Java代码 

<% String pageURL = "/templates/header.jsp"; %><%=pageURL%><jsp:include page= [color=red]"<%=pageURL%>" [/color]></jsp:include>
解析结果
String pageURL = "/templates/header.jsp";
out.print(pageURL);
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, [color=red]pageURL[/color], out, false);
<% String pageURL = "/templates/header.jsp"; %><%=pageURL%><jsp:include page= [color=red]"<%=pageURL%>" [/color]></jsp:include> 

 

解析结果String pageURL = "/templates/header.jsp"; out.print(pageURL); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, [color=red]pageURL[/color], out, false);

哈哈,这次 解析的时候 成功的将 page="<%=pageURL%>" 中的pageURL当成一个变量作为对应方法的参数了


我得到的结论就是:

首先就是一楼朋友说的,
在<jsp:include>中是支持<%=%>的。

具体的语法就是,在给page属性赋值的时候,如果想应用<%=%>。那么一定不要另外添加其它字符,这样就会将<%=%>中的变量成功解析为对应方法的参数。
否则会将引号中的内容当成一个死的字符串作为参数。

分享到:
评论
1 楼 lori_xj 2014-05-16  

相关推荐

    JSP:include和include指令区别

    JSP:include和include指令区别,对应我的博客 blog.csdn.net/svitter

    jsp:include与include实探

    NULL 博文链接:https://dreamzhong.iteye.com/blog/1127436

    jsp基础测试 期末考试

    考虑下面JSP文件代码片断: &lt;jsp:include page=”test2.jsp”&gt; &lt;jsp:param name=”username” value=”accp”/&gt; &lt;/jsp:include&gt; 以下( )代码片断放置在test2.jsp中不会导致错误。

    JSP中include指令和include行为的区别

     jsp:include page=” ” flush=”true”/&gt; 前者是指令元素、后者是行为元素。具体它们将在何处用?如何用及它们有什么区别?这应该是很多人看到它都会想到的问题。下面一起来看看吧。 通常当应用程序中所有的...

    JSP下动态INCLUDE与静态INCLUDE的区别分析

     用jsp:include动作实现 &lt;jsp include page=”included.jsp” flush&gt;它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE   用include伪码实现,定不会检查所含文件的变化,...

    2.4 include指令 JSP+AJAX

    2.4 include指令 JSP+AJAX2.4 include指令 JSP+AJAX2.4 include指令 JSP+AJAX2.4 include指令 JSP+AJAX

    使用jsp:include控制动态内容的方法

    本文实例讲述了使用jsp:include控制动态内容的方法。分享给大家供大家参考,具体如下: 清单 1. JSP include 伪指令 &lt;![CDATA[ &lt;&#37;@ page language=java contentType=text/html %&gt; &lt;html&gt; &lt;head&...

    JavaWeb开发技术-JSP动作元素.pptx

    在JSP页面中,为了把其他资源的输出内容插入到当前JSP页面的输出内容中,JSP技术提供了&lt;jsp:include&gt;动作元素。其语法格式为: &lt;jsp:include page="relativeURL" flush="true|false" /&gt; 指定被引入资源的相对路径 ...

    用jsp:include控制动态内容的方法.docx

    用jsp:include控制动态内容的方法.docx

    Java Web 实验四 掌握<jsp:include>动作的使用

    问题描述: 网上购物系统,商品包括mp3和mp4两项...中使用jsp:include动作包括了选购商品信息item.jsp文件。 实现步骤: 1.创建 index.jsp文件; 2.创建order.jsp文件; 3.创建item.jsp文件; 4.运行结果并完成实验报告。

    前端分页jsp实现(二)

    采用jsp开发的前端分页,抽取成一个公共的jsp,在需要的界面采用 &lt;jsp:include&gt;引入就行,白色按钮,黑色选中样式 &lt;div style="display: block;height: 200px;"&gt; &lt;jsp:include page="pagination.jsp" flush="true"&gt;...

    JSP中动态include与静态include的区别介绍

    动态INCLUDE 用法:&lt;jsp page=”included.jsp” flush=”true”&gt; 说明:它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数,先编译之后再进行处理。 原因:1、静态include的结果是把其他jsp引入...

    jsp的Include方式

    jsp的Include方式

    基于jsp:included的使用与jsp:param乱码的解决方法

    本篇文章是对jsp:included的使用与jsp:param乱码的解决方法进行了详细的分析介绍,需要的朋友参考下

    springMVC使用jsp:include嵌入页面的两种方法(推荐)

    下面小编就为大家带来一篇springMVC使用jsp:include嵌入页面的两种方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    JSP程序设计与案例实战

    内容摘要:JSP程序设计与案例实战PPT,里面覆盖了网页前端“三剑客”知识点、如何安装配置JSP运行环境、JSP脚本元素(JSP表达式、声明、Script)及其指令(include指令、page指令、taglib指令)、JSP隐式对象(out、...

    jsp的include的两种用法

    jsp的include的两种用法 jsp的include的两种用法

    jsp页面错误信息

    &lt;tr&gt;&lt;td colspan="2"&gt;&lt;jsp:include page="view/AdminTop.jsp" /&gt;&lt;/td&gt;&lt;/tr&gt; &lt;td width="180" valign="top"&gt;&lt;jsp:include page="view/AdminLeft.jsp"/&gt; ...

    jsp动态网页学习

    jsp指令标签(page,taglib,include)、动态标签(jsp:include,jsp:forward,jsp:param,jsp:useBean,jsp:setProperty,jsp:getProperty),案例demo

    可以include的jsp独立分页

    有很详细的注释解释,是中国人都应该看的懂,在你需要的分页的页面嵌入这个jsp,通过修改它的默认属性,和使用它的内置方法,就可以达到分页效果,而且可以有自己的样式效果,以下是例子: 你的页面头顶部加入&lt;%@include ...

Global site tag (gtag.js) - Google Analytics