Web应用中页面跳转的路径问题

来源:互联网 发布:c 调用c dll 源码 编辑:程序博客网 时间:2024/05/16 05:03

在做web开发的时候就路径的问题一直苦恼今天上网查资料 发现了一篇非常好的资料,转载来研究!!


1.jsp页面中的路径


一般地我们将在<head></head>中的<base>标签中设置网页的基本路径。 


所谓基本路径是指无论该jsp页面在网站何目录下,在该jsp中的请求元素都是依照这个基本路径进行资源定位的,这就解决了因该jsp所在目录的不同而对该请求元素的资源定位不同 eg:

现有目录结构如下

------webapp

---------------a目录

                   | a1.jsp

                   | a2.jsp

---------------b目录

                   | b.jsp

                   | b.png

---------------c目录

-------------------d目录

                         | d.jsp

                         | d.jpg


没有设置<base>的情况

  1. a1.jsp中访问a2.jsp 
        -> a1中请求元素<a href="a2.jsp">a2.jsp</a>

  2. a1.jsp中访问b.jsp
        -> a1中请求元素<a href="../b/b.jsp">b.jsp</a>

  3. a1.jsp中访问d.jsp
        -> a1中请求元素<a href="../c/d/d.jsp">d.jsp</a>


可以见得,资源的定位是由a1所在目录决定的,下面我们再看看设置<base>后的效果:

设置<base>的情况

<%

String path = request.getContextPath();

String basePath = request.getScheme() + "://" 

    + request.getServerName() + ":"

    + request.getServerPort()+path+"/";

%>

<base  href="<%=basePath%>">

  1. a1.jsp中访问a2.jsp 
    -> a1中请求元素<a href="a/a2.jsp">a2.jsp</a>

  2. a1.jsp中访问b.jsp
        -> a1中请求元素<a href="b/b.jsp">b.jsp</a>

  3. a1.jsp中访问d.jsp
        -> a1中请求元素<a href="c/d/d.jsp">d.jsp</a>


通过对比相信你已经明白了设置与不设置的区别了。 没错,设置<base>后 资源的定位不再由a1所在目录决定的, 而是有webapp目录决定。这样有如下几点好处:

  1.  不需要在页面中以../或../../来回到上级或上上级目录

  2.  都是相对于WebRoot目录,实现了路径的统一

  3.  当某一资源位置变动时 只需Ctrl+f替换 有些工具会自动修改请求元素的定位路径 象dreamwaver等


补充

1. jsp页面中请求元素中的最前面的/代表的是"主机地址:端口号/", 如:

    <a href="/a.jsp">a.jsp</a> 的完整路径为http://localhost:8080/a.jsp

2. String basePath = request.getScheme()+"://"+request.getServerName()+":"

   +request.getServerPort()+path+"/"; 

这段话的含义先看下http协议的请求信息都包含哪些东西:


请求头信息

POST /myproject/backmanager/CheckInformationSevrlet HTTP/1.1

Host: localhost:8080

User-Agent: Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.22) Gecko/20110905 Ubuntu/10.04 (lucid) Firefox/3.6.22

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-cn,zh;q=0.5

Accept-Encoding: gzip,deflate

Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7

Keep-Alive: 115

Connection: keep-alive

Referer: http://localhost:8080/myproject/backmanager/login.jsp 

Cookie: JSESSIONID=51C310206938FBA5F44CBEED0D219EAF 


响应头信息

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Type: text/html;charset=UTF-8

Content-Length: 708

Date: Sun, 18 Sep 2011 13:28:35 GMT



request对象封装了由客户端生成的http请求的所有细节( 请求参数,属性,请求头信息,cookies,数据)我们只关注头信息

request.getScheme()------->http

request.getServerName()-------->localhost

request.getServerPort()------------->8080

request.getContextPath()-------------->myproject


2. servlet中的路径

servlet中主要涉及路径的地方有两个: 重定向, 转发.


两者的区别:

重定向:是当服务器端执行重定向语句时, 将向客户端发送一条命令, 让浏览器重新访问新的地址, 浏览器发出两次请求。同时服务器端在执行完重定向语句后,还会继续执行重定向下面的语句,所以一般不要在重定向语句后写其他语句, 直接return就好了

转发:当服务器执行转发语句时,服务器将调用转发的页面的servlet(服务器内部转) ,再由转发页面将结果返回给客户端,rquest进行了封装传递, 调用之后别忘了return。


重定向的路径:

response.sendRedirect(request.getContextPath()+"/a/a.jsp");


JavaEE5.0对sendRedirect的解释

the servlet container must convert the relative URL to an absolute URL before sending the response to the client. If the location is relative without a leading '/' the container interprets it as relative to the current request URI.If the location is relative with a leading '/' the container interprets it as relative to the servlet container root.(tomcat所在根目录不保含具体的project名称)


相信英语说的过去的都能看懂, 原文解释的比较地道, 我就不多说了。

这句语句指重定向到 http://localhost:8080/myproject/a/a.jsp

转发中的路径:

request.getRequestDispatcher("/a/a.jsp").forward(request, response);

这句语句指 转发到 http://localhost:8080/myproject/a/a.jsp


补充:

1.servlet页面中请求元素中的最前面的/代表的是"主机地址:端口号/project/". 相当于

 request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"

所以转发直接按照相对webapp进行资源定位就哦了

 

2.web.xml中的路径( 这个是具体项目的相关web.xml配置文件, 而不是servlet /jsp, 容器全局的web.xml配置文件) 

这里的路径/的含义和servlet页面中的一样相当于:

request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"


关于jsp+servlet开发下的路径问题总结:http://hi.baidu.com/it_crazyer/item/318d105051561dd6d58bac73


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

为了避免jsp跳jsp,servlet跳jsp,forward方式跳转,sendredirect跳转产生的路径问题, 对于jsp和使用sendredirect跳转的servlet,采用直接使用带容器路径[string request.getcontextpath()]的绝对路径就能完全解决,即:

<%

          string contextpath = request.getcontextpath();

          string url = contextpath + "/user/login.jsp";

%>       

<a href="<%=url%>"> login</a>

另一种方法就是使用 jsp页面的正则表达式 。 ${ctx} 这样就可以获取 ctx的值 与<%=ctx%>的功能一样。


 string contextpath = request.getcontextpath();

      string targetpath = contextpath + "/user/login.jsp";

      requestdispatcher rd = request.getrequestdispatcher(targetpath);

      rd.forward(request, response);

      ......


 对于使用forward跳转的servlet,则不要加容器路径,否则就重复出现 容器路径。

因为在servlet中以forward方式使用的 “/” 表示的根为“host:port/app/”,包含了应用路径, 而
在servlet中以sendredirect方式使用的 “/” 表示的根为“host:port”,不包含应用路径。

0 0