日期:2014-05-16  浏览次数:20543 次

jsp:include 中路径问题
这里我主要是在讲自己在解决这个问题过程中对具体问题的理解,有可能前后矛盾,因为我是把我的认识过程顺序的说出来,想让大家帮忙指出不对的地方。
因为问题解决了,可是道理认识歪了,后患无穷啊。特别是对我这个非科班出身的2手程序员。

PS:不知道怎么在入门讨论中发普通的帖子。提示我没积分了,那就发个提问帖,本来这贴目的其实也是在“提问”


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


从一个需求说起(自己之前对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",