JavaWeb开发中访问的地址是否有斜杠“/”(绝对路径和相对路径)的区别

刚开始做开发的时候,对于要路径前是否加斜杠“/”一直比较疑惑,即绝对路径和相对路径问题。最近写了一个demo用来测试这个问题,对这个问题做了一个总结。

这里先贴上项目的结构,方便能看到各资源的实际位置。

JavaWeb开发中访问的地址是否有斜杠“/”(绝对路径和相对路径)的区别_第1张图片


下面是web.xml的配置,主要是各个servlet的资源路径



  pathDemoApp
  
    index.html
    index.jsp
  
  
  
    Demo1
    com.lk.demo.Demo1
  
  
    Demo1
    /demo1
  
  
  
    Demo2
    com.lk.demo.Demo2
  
  
    Demo2
    /demo2
  
  
  
    Demo3
    com.lk.demo.Demo3
  
  
    Demo3
    /test/demo3
  
  
  
    Demo4
    com.lk.demo.Demo4
  
  
    Demo4
    /demo4
  
  
  
    Demo5
    com.lk.demo.Demo5
  
  
    Demo5
    /test/demo5
  
  
  
    Demo6
    com.lk.demo.Demo6
  
  
    Demo6
    /test/demo6
  


需要强调,路径的问题要区别开是“服务器(或者说servlet处理的路径)”还是“客户端(即浏览器要发送的请求)”。


1、先说“客户端”:

1.1 HTML页面的请求。

下面的代码是在HTML页面中,浏览器请求图片资源的情况。

test1.html





Insert title here


  
  
  

结果如下图所示,只有第一个图片请求成功。

JavaWeb开发中访问的地址是否有斜杠“/”(绝对路径和相对路径)的区别_第2张图片

1.2 Response的重定向。

response.sendRedirect(path);

虽然response重定向资源是在servlet代码中实现的,但是,是将要重定向的路径返回给浏览器,让浏览器重新请求,因此,其规律和HTML页面请求资源是一样的,所以这里将重定向归为客户端请求这一类。

代码如下:

Demo3.java

package com.lk.demo;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 该类用于测试Response的重定向
 * 将该类的访问路径特别设置为/test/demo3
 */
public class Demo3 extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("我是Demo3");
    
    /*
     * 总结:
     * response的重定向方法,是将路径返回给浏览器,让浏览器重新请求,因此可以发现,
     * 重定向的规律和浏览器在页面中发送请求的规律是一样的。
     * “/”表示服务器站点的根路径,这里是 http://localhost:8080/,
     * 如果参数路径前不加“/”,则浏览器会将URI的最后一个斜杠后的资源名称替换为参数请求的路径。
     */
    response.sendRedirect("/pathDemoApp/demo4");//正确
//    response.sendRedirect("pathDemoApp/demo4");//路径为http://localhost:8080/pathDemoApp/test/pathDemoApp/demo4
//    response.sendRedirect("/demo4");//错误路径为http://localhost:8080/demo4
//    response.sendRedirect("demo4");//错误路径为http://localhost:8080/pathDemoApp/test/demo4
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }

}

HTML中,“/”表示的是服务器站点的根路径,案例中为http://localhost:8080/;

如果不加“/”,则是在当前页面的路径基础上,将请求的URI替换掉最后一个“/”后的资源名称。


2、服务器

2.1 ServletContext.getRealPath()方法获取资源的路径。

ServletContext的getRealPath方法可以获取项目下任何位置资源的路径。

Demo2.java

package com.lk.demo;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用于测试ServletContext的getRealPath方法的结果
 *
 */
public class Demo2 extends HttpServlet {
  
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*
     * ServletContext的getRealPath方法可以获取项目下任何资源的路径
     * 总结:
     * 该方法都是从项目根路径(即站点+项目名称)下查找参数传递的资源路径,不论参数前是否有斜杠。
     * 然后将参数代表的资源路径拼接到项目根路径之后。
     */
    String path1 = getServletContext().getRealPath("pathDemoApp/iamge/pic.jpg");
    System.out.println(path1);
    //  D:\WorkProgramFiles\apache-tomcat-7.0.35\webapps\pathDemoApp\pathDemoApp\iamge\pic.jpg
    String path2 = getServletContext().getRealPath("/iamge/pic.jpg");
    System.out.println(path2);
    //  D:\WorkProgramFiles\apache-tomcat-7.0.35\webapps\pathDemoApp\iamge\pic.jpg
    String path3 = getServletContext().getRealPath("iamge/pic.jpg");
    System.out.println(path3);
    //  D:\WorkProgramFiles\apache-tomcat-7.0.35\webapps\pathDemoApp\iamge\pic.jpg
    String path4 = getServletContext().getRealPath("/pic.jpg");
    System.out.println(path4);
    //  D:\WorkProgramFiles\apache-tomcat-7.0.35\webapps\pathDemoApp\pic.jpg
    String path5 = getServletContext().getRealPath("/");
    System.out.println(path5);
    //  D:\WorkProgramFiles\apache-tomcat-7.0.35\webapps\pathDemoApp\
    String path6 = getServletContext().getRealPath("");
    System.out.println(path6);
    //  D:\WorkProgramFiles\apache-tomcat-7.0.35\webapps\pathDemoApp
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }

}

该方法都是从项目根路径(即站点+项目名称)下查找参数传递的资源路径,不论参数前是否有斜杠“/”, 然后将参数代表的资源路径拼接到项目根路径之后。


2.2 Request的转发请求。

request.getRequestDispatcher(path).forward(request, response);

Demo5.java

package com.lk.demo;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 用于测试Request的转发
 * 将该类的访问路径特别设置为/test/demo5
 */
public class Demo5 extends HttpServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    /*
     * 总结:
     * 经过测试,可以发现
     * “/”表示项目的根路径,这里是 http://localhost:8080/pathDemoApp/,
     * 如果参数路径前不加“/”,则会将当前资源的请求路径中,最后一个斜杠后的资源名称替换为参数请求的路径。
     */
    
    System.out.println("我是Demo5");
    
//    String path = "/pathDemoApp/test/demo6";//错误404:/pathDemoApp/pathDemoApp/test/demo6
//    String path = "pathDemoApp/test/demo6";//错误404:/pathDemoApp/test/pathDemoApp/test/demo6
    String path = "/test/demo6";//正确
//    String path = "test/demo6";//错误404:/pathDemoApp/test/test/demo6
    
    request.getRequestDispatcher(path).forward(request, response);

    System.out.println("又回到了Demo5");
    
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
  }

}

该方法中,“/”表示项目的根路径,这里是 http://localhost:8080/pathDemoApp/;

 如果参数路径前不加“/”,则会将当前资源的请求路径中,最后一个斜杠后的资源名称替换为参数请求的路径,不加“/”类似于重定向的请求。


总结:

上述的例子是我现在能想到的一些情况。

对于浏览器端,“/”表示的是服务器根站点,即http://localhost:8080/ 。

对于服务器端,“/”表示的是项目的根路径,即http://localhost:8080/pathDemoApp/ 。

总的来说,可以发现,在使用资源路径时,最好使用当前项目的根据路,这样不会出现什么大问题。

对于浏览器请求,比如在jsp的渲染引擎中,我们可以使用request.getContextPath的方法获取当前项目的项目名称,在后面拼接具体资源的路径,以避免在代码中将项目名称写为固定值。


你可能感兴趣的:(JavaWeb)