请教关于如何解决项目中绝对路径的问题
[size=large][b]请大家指教一下,是否有什么办法能解决这种问题。[/b][/size]
标题描述的不是很清晰,下面是问题的发生情况:
1、过去系统中所有的跳转、JSP页面中图片的引用都以绝对路径来写,例如:MyJsp.jsp
[code="java"]
This is my JSP page.
跳转
[/code]
2、项目是部署到resin3.1.6中的webapps\ROOT目录中,resin.conf没有做修改:
[code="java"]
[/code]
3、访问路径即服务器地址,例如: http://localhost/MyJsp.jsp
在这种情况下,项目页面跳转,图片显示都没有问题,因为'/'直接是localhost
[size=medium][b]问题所在:[/b][/size]
当需要把项目发布为其他应用名的时候,问题显现出来,所有的图片和页面跳转都出现错误。例如:
a. 由于要在resin下部署其他应用,所以把已有应用发布到 resin/webapps/myapp/文件夹中
b. 当访问http://localhost/myapp/MyJsp.jsp时,aa1.gif无法显示,查看图片路径为:http://localhost/aa1.gif
c.点击跳转链接时,页面跳转到http://localhost/other.jsp,当然,肯定找不到这个页面,报404错误
以下是我目前的解决方案,但我感觉不是最优的。
通过虚拟主机的方式来解决这种问题。
[code="java"]
myapp.com
<root-directory>.</root-directory>
<web-app id="/" root-directory="webapps/myapp"/>
[/code]
[b]问题补充:[/b]
补充一下:
本人不想通过修改页面链接的方式来解决这个问题,因为如果要修改页面中链接路径的话,需要大量的工作量,我认为不是最好的方式。
谢谢firefly.li 的回答,您的方式确实可以,不过不是我想要的方式。
[b]问题补充:[/b]
--------感谢3楼energykey回答------------
你说的方式确实可以解决问题,但这个filter相当于是在项目之外的,那如果我在resin下部署多个应用,譬如webapps/test1,webapps/test2...
那如何来重写URL。所以我觉得这不是我想要的答案
其实我只是希望知道是否能够通过修改web.xml或者服务器的配置来解决这种绝对路径的问题。
也感谢4楼的回答
你说的这种方式我考虑过,也试验过,不过没有成功~~~
[b]问题补充:[/b]
再次感谢energykey的指点。以为真的有捷径。不过目前项目使用虚拟主机用起来还是很方便,这种绝对路径的写法到底是对是错我不是很清楚,我所知道的是这种绝对路径写起来很方便,所有的链接前面一个‘/’就全部从根目录开始,不用写那些讨厌的../....,更不用担心目录层次结构的更改,并且也有虚拟主机的方式来解决这种问题。
我想,在实际生成环境中,大部分的系统都会有自己的主机(至少是虚拟的)、有自己的域名,所以还是可以考虑延续这种方式。
[quote]其实我只是希望知道是否能够通过修改web.xml或者服务器的配置来解决这种绝对路径的问题。 [/quote]
其实你自己也知道不可能。
这里的所有讨论只不过都是亡羊补牢而已,楼主的代码写法已经错了,现在只是怎么弥补,我记得我第一天去第一家公司,当时的上司就教导我,所有链接要么用相对路径,比如“index.html”,不关你是ROOT下还是其他APP下,绝对正确,因为是相对于当前路径而言的。要么就用绝对路径,但绝对路径必须使用,这句话的目的其实也就是多加了一个<%=request.getContextPath()%>。
不过根据我的经验我们最好使用相对路径,因为WEB常常会涉及到JS来操作链接的问题,而<C:url 只能处理预先需要编译的,不能处理AJAX即时获得的路径,所以我数据库里图片存储路径一般是"file/user/*",而不是"/file/user/*",如果使用后者,就会出现楼主一样的问题。
楼主回头是岸吧,你这种方法已经错了,所以不必去为一种错误的写法花费太多的时间,只要能解决目前的问题就行了,剩下的就是好好总结一下以后如何避免现在的问题。
使用request.getContextPath()获取路径。
我觉得可以使用filter实现。既然你用了绝对路径,那就得将绝对路径进行到底了。但是由于你默认的请求都是到root里了,所以你这个filter必须是放到root下的程序里去【有点怪,但应该有效】。
1.拦截所有request请求。
2.getRequestURI()。获取请求URL.
3.重写URL。楼主应该自己知道自己的算法吧,我不知道所以不写了,把对应部分替换掉就可以了。这里可以通过getContextPath()获取真实的contextPath。
4.redirect.over~
你可以尝试一下,我觉得这个移植性也不错的,以后你要改回root方式,去掉filter就是了,要改APP应用名字,filter里改改也容易的。
在Myeclipse中新建一个JSP文件,会自动的生成一些代码如下:
[code="java"]
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">