现在的位置: 首页 > 综合 > 正文

【转载】JSP、Servlet以及项目中可能遇到的路径问题

2013年10月25日 ⁄ 综合 ⁄ 共 5593字 ⁄ 字号 评论关闭

打个比方:
你现在的路径是
http://localhost:8080/test/A.jsp

A.jsp在你的根目录/中但是B.sp是在
/B/中,所以B.jsp在A.jsp的下一级目录中
你要跳转到
B/B.jsp

现在用两种方式
1:
request.getRequestDispatcher("B.jsp").forward(request,response);
因为是服务器端跳转,所以虽然执行的是B/B.jsp但是你的地址栏路径依然是
http://localhost:8080/test/A.jsp

那么也就意味着你现在的所有文件依然是在/目录中查找。
2:
但是如果你你在A.jsp中用response.sendRedirect("B/B.jsp"),那么你的地址栏地址是http://localhost:8080/test/B/B.jsp

那么也就意味着你现在要找文件的话都是从/B目录中开始.所以用不同的方式转会存在不同的路径问题.
现在假如你的目录结构为
/A.jsp
/B/B.jsp
/client/login.jsp
假设你是由A-->B-->login.jsp跳转的话假设B中用的是response.sendRedirect()方法
那么在A.jsp中如果你用第一种跳转方式的话就B.jsp中就要是response.sendRedirect("client/login.jsp");
因为此时的寻找地址是在/目录中,而client就在/目录中,所以一进去就找到了login.jsp
但是如果你在A.jsp中用的是客户端跳转方式也就是第二种方式的话B.jsp中你就要写为
response.sendRedirect("../client/login.jsp");
因为此时的地址栏地址应该是地址是http://localhost:8080/test/B/B.jsp

也就意味着你的开始寻址位置是/B中,但是client不在B中,所以要往上一层才找到client目录,进去以后才找到login.jsp

同样的目录结构但是要根据实际地址找地址,就像找人一样
常见的超链接也是客户端跳转,你都用html的话当然也就不存在服务器端跳转,也就不存在路径的复杂问题,以后你要是用servlet开发,或者相关的mvc架构都有这个问题.
还有不同的服务器也会有不同的路径解析方式。
希望对你有帮助



提:假设你的Http地址为
http://192.168.0.1/


你的web应用为webapp,那么你的web应用URL为
http://192.168.0.1/webapp/


web应用的目录结构:

webapp/

web-inf/

classes/

lib/

web.xml


handleservlet

/handleservlet此映射是相对于当前web应用的

 

user/

a.jsp

b.jsp

images/

css/

js/


所有相对路径都是由“/”开头的。如:/image/a.gif,/user/main.jsp,大家知道在html中的相对路径是这样的:

有个html文件:a.html,其中有,其中href属性表示引用的css文件的路径。

one.css:表示one.css和a.hmtl处于同一个目录

user/one.css:表示one.css处于a.html所在目录的子目录user中。

../one.css:表示one.css位于a.hmtl上一级目录下,

../../one.css:表示one.css位于a.hmtl上一级目录的上一级目录下,

./:表示和a.hmtl同一目录

我们称上述相对路径为html相对路径

1、服务器端的地址

服务器端的相对地址指的是相对于你的web应用的地址,这个地址是在服务器端解析的(不同于html和javascript中的相对地址,他们是由客户端浏览器解析的)也就是说这时候在jsp和servlet中的相对地址应该是相对于你的web应用,即相对于
http://192.168.0.1/webapp/


的。

其用到的地方有:

forwarder:servlet中的
request.getRequestDispatcher(address);这个address是在服务器端解析的,所以,你要forwarder到
a.jsp应该这么写:request.getRequestDispatcher(“/user/a.jsp”)这个/相对于当前的web应用
webapp,其绝对地址就是:

http://192.168.0.1/webapp/user/a.jsp


sendRedirect:在jsp中

2、客户端的地址

所有的html中的相对地址都是相对于
http://192.168.0.1/


的,而不是
http://192.168.0.1/webapp/


的。

Html中的form表单的action属性的地址应该是相对于
http://192.168.0.1/


的,所以,如果提交到a.jsp为:action=”/webapp/user/a.jsp”;提交到servlet为action=”/webapp/handleservlet”

Javascript也是在客户端解析的,所以其相对路径和form表单一样。

3、站点根目录和css路径问题

我们称类似这样的相对路径/webapp/….为相对于站点根目录的相对路径。

当在jsp中引入css时,如果其相对路径相对于当前jsp文件的,而在一个和这个jsp的路径不一
样的servlet中forwarder这个jsp时,就会发现这个css样式根本没有起作用。这是因为在servlet中转发时css的路径就是相对于
这个servlet的相对路径而非jsp的路径了。所以这时候不能在jsp中用这样的路径:或者类似href="one.css"和../..
/one.css的html相对路径是相对于引用这个css的文件的相对路径。而在servlet中转发时就是相对于这个servlet的相对路径了,因
为jsp路径和servlet路径是不一样的,所以这样的引用肯定是出错的。

所以这个时候,要用站点根目录,就是相对

http://192.168.0.1/

的目录,以“/”开头。

因此上述错误应更正为href=”/webapp/one.css”类似的站点根目录的相对目录。这样在servlet转发后和jsp中都是相对于站点根目录的相对路径,就能正确使用所定义的css样式了。

在JSP中的如果使用 "相对路径" 则有可能会出现问题.

因为 网页中的 "相对路径" , 他是相对于 "URL请求的地址" 去寻找资源.

上面这句话是什么意思呢 ?
举个例子:
假如我们有一个项目: MyApp
在该项目下, 有一个jsp文件夹
该文件夹下包括:
login.jsp     // 登陆页面
register.jps // 注册页面


我们在浏览器中输入地址 (注意: 地址的内容):
http://localhost:8080/MyApp/jsp/login.jsp
这时候, 浏览器会链接到 "登陆页面" (login.jsp)
在login.jsp文件内包含了如下 "部分代码":
<a href="jsp/register.jsp">注册用户</a>


那么,如果我们点击这个链接,就会在浏览器地址栏中, 出现如下错误链接:

http://localhost:8080/MyApp/jsp/jsp/register.jsp


看~~
为什么会出现"/jsp/jsp/register.jsp"呢?
因为, 网页中的"相对链接", 是相对于你所 "请求的URL路径" 所决定的.


即:

因为这里请求路径是:http://localhost:8080/MyApp/jsp/login.jsp

那么, 浏览器 就会在这个路径下(即:http://localhost:8080/MyApp/jsp/)去找 jsp/register.jsp
所以就会出现如下错误内容:

http://localhost:8080/MyApp/jsp/jsp/register.jsp

上面的问题,就是调用页面和被调用页面的URL不同所造成的,
此类错误也常常会出现在2个页面之间进行 "转发"(forward) 操作的时候。
因为forward是在后台进行的,对客户端来说是透明的。(即: URL不改变,而数据内容却是另一个页面返回来的。。。)

那么如何解决这问题呢?

(一)方法一:直接采用绝对路径 (不推荐)
在JSP页面端,获得本项目的绝对地址(如果你的项目叫MyApp,那么获得到的地址就是 http://localhost:8080/MyApp/):
代码如下:
<!-- **************方法一***************** -->
<%@ page language="java" pageEncoding="GBK" contentType="text/html;charset=gbk" isELIgnored="false"%>
<%
String path = request.getContextPath();
// 获得本项目的地址(例如: http://localhost:8080/MyApp/)赋值给basePath变量
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
// 将 "项目路径basePath" 放入pageContext中,待以后用EL表达式读出。
pageContext.setAttribute("basePath",basePath);
%>
<html>
<head></head>
<body>
<a href="${pageScope.basePath}jsp/register.jsp">
</body>
</html>
<!-- *************************************-->


我们可以看到,在标签<a>中的href属性内,我们直接采用了
“本项目路径 ${pageScope.basePath}” 加上 "jsp/register.jsp" ,
从而构成一个绝对路径(即: http://localhost:8080/MyApp/jsp/register.jsp)


但是这样做有一个很不好的地方,那就是我们必须要在每个链接的前面都要加上 “${pageScope.basePath}”
如果这样做的话,将是一件很可怕的事情。


(二)方法二: 利用html中的<base>标签(推荐)
下面是对html中的<base>的介绍:
base 元素可规定页面中所有链接的基准 URL
默认情况下,页面中的链接(包括样式表、脚本和图像的地址)都是相对于当前页面的地址(即:浏览器地址栏里的请求URL)。
我们可以使用<base>标签中的href属性来设置,所有的“相对基准 URL”。


上面说的是什么意思呢?我们来看看代码就知道咯~~

这是JSP端的代码
下面的代码 (十分类似上面 "方法一" 中的JSP代码)
但是这里我们并没有采用 ${pageScope.basePath}+"相对路径地址" 的方法,
而是采用了html文件中的<base>标签:
代码如下:
<!-- *************JSP代码******************-->
<%@ page language="java" pageEncoding="GBK" contentType="text/html;charset=gbk" isELIgnored="false"%>
<%
String path = request.getContextPath();
// 获得项目完全路径(假设你的项目叫MyApp,那么获得到的地址就是 http://localhost:8080/MyApp/):
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
   <!-- base需要放到head中 -->
   <base href="<%=basePath%>">
</head>
// 这里我们就可以直接使用相对路径(即: 相对于base标签)
<a href="jsp/login.jsp">Login</a>
</html>
<!-- *************************************-->


大概看完了上面的代码,或许您还是有些疑惑 *_*~~
不过当您看到了,下面的代码,可能就豁然开朗了 (*^__^*) 嘻嘻……。


当我们去执行上面的那段JSP代码后,我们可以在浏览器中可以查看,他所返回给客户端的html代码:
执行完上述JSP后,所返回的html代码如下:
<html>
<head>
   <base href="http://localhost:8080/MyApp/">
</head>
// 设置了<base>后,相对路径,相对于的就是base中的路径,而不再是浏览器地址的请求路径啦~~~
<a href="jsp/login.jsp">Login</a>
</html>


我们可以看到JSP返回的html代码中,包含了<base href="http://localhost:8080/MyApp/">内容。
也就是说,在本html文件中,遇到的所有 “相对链接(例如:<a href="jsp/login.jsp">)”,都是相对于base
的路径(即:http://localhost:8080/MyApp/),所以我们就可以尽兴的使用 相对链接,而不必担心转发操作(forward)


或 请求地址不同不同所造成的页面无法找到的错误啦~(HTTP: 404)。。。

抱歉!评论已关闭.