java中的路径问题总结

页面路径

  • 如果是页面的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()时设定的路径

posted @ 2015-02-26 21:07  iMouseWu  阅读(471)  评论(0编辑  收藏  举报