页面路径

  • 如果是页面的href/src前面加一/比如localhost:8080/test/test1/test_test页面加载js
  • < a href="/c.js">那么久相当于localhost:8080/c.js
  • 如果是< a href="c.js">那么久相当localhost:8080/test/test1/c.js
  • 如果是< a href="../c.js">那么久相当于localhost:8080/test/c.js当前目录的上一级,是相对于url中的上记忆

spring加载xml文件

spring加载xml文件会去加载jar包里面的配置
但是同时出现了2个同样名字的文件(并且他们的路径是一样)的话。那么spring只会加载其中一个
e.g conf/application-context.xml和conf/admin/admin-application-context.xml会同时被加载。但是conf/application-context.xml在jar包里面也有一个conf/application-context.xml那么这个xml就不会被加载。。这个时候需要机上classpath*

ApplicationContext context = new
 ClassPathXmlApplicationContext("classpath*:**/*application-context.xml");来创建ApplicationContext对象的话,Spring只会加载
 bin/application-context.xml和bin/admin/admin-application-context.xml,


而jar包中的配置文件并不会被加载。这是因为Spring使用class path加载配置文件时需要借助JDK的ClassLoader.getResources(String name)方法,而该方法有一个局限:当传入的参数为空字符串时,即我们本意是想从根目录获取文件,这时JDK只会返回存在于文件系统中的资源,而在jar包中的资源并不会被返回

我们在eclipse中写个简单的测试类就能很容易看到这点:

ClassLoader loader = Thread.currentThread().getContextClassLoader();
 Enumeration resources = loader.getResources("");
 while (resources.hasMoreElements()) {
 URL url = (URL)resources.nextElement();
 System.out.println(url);
 }


运行测试类后,输出结果为:

file:/D:/myworkspace/spring-study/bin/
file:/D:/ProgramFiles/eclipse3.2/configuration/org.eclipse.osgi/bundles/47/1/.cp/


可以看到,获得的资源路径中并不包含jar包中的路径,因此jar包中的配置文件自然不能被Spring加载了

Class的getResourceAsStream,getResource和ClassLoader的getResource,getResourceAsStream

  • 这里Class的getResourceAsStream和ClassLoader的getResourceAsStream分别调用的是Class的getResource和ClassLoader的getResource返回结果的openStream方法。
  • Class的getResource实际上还是调用的是ClassLoader的getResource。具体的Class的源代码如下:
public java.net.URL getResource(String name) {
      name = resolveName(name);
      ClassLoader cl = getClassLoader0();
      if (cl==null) {
       // A system class.
      return ClassLoader.getSystemResource(name);
      }
      return cl.getResource(name);
  }

  private String resolveName(String name) {
    if (name == null) {
        return name;
    }
    if (!name.startsWith("/")) {
      Class c = this;
      while (c.isArray()) {
          c = c.getComponentType();
      }
      String baseName = c.getName();
      int index = baseName.lastIndexOf('.');
      if (index != -1) {
        name = baseName.substring(0, index).replace('.', '/')+"/"+name;
      }
    } else {
      name = name.substring(1);
    }
    return name;
  }

这里的resolveName方法主要是构建ClassLoader的getResource读取的path的绝对路径。
所以如果Clas.getResource("A")中A为:

  • "/XXX/a.xml"那么将会去读取根目录下(具体是编译的classes文件夹)的XXX下的a.xml文件
  • "a.xml"那么就会读取该Class下的a.xml文件(比如说该Class为com.a.b)那么将会调用相对于根目录下的com.a文件下的a.xml文件
  • 注意点:
  • 这里的读取的文件必须是在工程下的文件夹中,在其它地方(比如磁盘)中是读取不到的。
  • 这里的根目录是该程序入口所对应的根目录。比如A子工程调用B子工程的一个类的C方法。C方法通过getResource读取配置文件D。这个时候相对的根路径是相对于A子工程来说的,所以当A和B的classes文件夹中都有文件D。那么读取的是A下的文件D。

附录

  • servlet
  • request.getRequestDispatcher(“/user/a.jsp”)这个/相对于当前的web应用webapp
  • response.sendRedirect("/rtccp/user/a.jsp")
  • request
  • getRequestURI
  • getContextPath
  • getServletPath
  • getRealPath
  • ServletContext
  • getRealPath
  • File (File directory = new File(".")和File directory = new File(".."))
  • getCanonicalPath
  • getAbsolutePath
  • getPath
  • getAbsolutePath

对于getCanonicalPath()函数,“."就表示当前的文件夹,而”..“则表示当前文件夹的上一级文件夹
对于getAbsolutePath()函数,则不管”.”、“..”,返回当前的路径加上你在new File()时设定的路径
至于getPath()函数,得到的只是你在new File()时设定的路径