JavaWeb路径知识概括

194 阅读13分钟

@TOC

路径和斜杠和反斜杠的关系

简述:

  • 路径一般用斜杠或反斜杠表示。

路径

//获取当前用户根目录为 C:\Users\Shinelon\IdeaProjects\shangguigu
String property = System.getProperty("user.dir");
System.out.println(property);

//获取创建file的绝对路径 C:\Users\Shinelon\IdeaProjects\shangguigu\myFile.txt
//创建时使用相对路径-----相对于当前用户根目录的路径
File file = new File("myFile.txt");
String absolutePath = file.getAbsolutePath();
System.out.println(absolutePath);

路径有相对路径和绝对路径两种:

  • 当我们使用绝对路径,就是从盘符开始的路径如D:\Users\Shinelon......,绝对路径比较简单,我就不多讲了。
  • 当我们使用相对路径时,JavaIO包中是相对于当前用户目录来分析相对路径的。我们可以调用System.getProperty("user.dir")来得到这个相对于当前用户目录的路径。因此如果我们创建一个文件时使用相对路径,则此文件放在当前用户目录中。
  • 而当前用户目录也就是JVM启动目录,也就是说JVM在哪启动,这个目录就在哪。也就是工作环境目录。
  • System.getProperty(“user.dir”)方法返回的是执行运行Java程序命令的路径。

java io的相对路径 - jvm 启动路径:

  • 按照上面jdk文档上讲的这个相对路径是”相对当前用户目录”也就是”java虚拟机的调用目录”.更明白的说这个路径其实是我们在哪里调用jvm的路径。

  • 通过tomcat运行的默认是在tomcat的bin目录下。

  • idea通过main方法启动的 jvm是在项目根目录上启动的。

  • 通过控制台运行的,在哪执行就是哪个路径。

当我们在相对路径使用斜杠开头时如:

//打印结果为:E:\myFile.txt
File file = new File("/myFile.txt");
System.out.println( file.getAbsolutePath());
  • 说明加斜杠意味着在当前的目前的根目录中。(即当前工作目录的根目录中,也就是盘符中)

斜杠和反斜杠

斜杠和反斜杠易记方式:

  • 斜杠/ 就是八字中的第一笔
  • 反斜杠就是八字中的第二笔
  • 总结来说就是一笔是斜杠,二笔是反斜杠。

java中的输出反斜杠或者双引号的时候为什么要用一个反斜杠放前面:

  • 因为引号和反斜杠在字符串里都是有特殊含义的,所以为了避免语意上的冲突,前面专就加上了反斜杠,相当于属一次转码了,
  • 你也可以这样看,转义字符\n是换行,那\\就表示的是\,\"表示的是“。
  • 而在其他环境如文件系统或者命令行则不用。

斜杠和反斜杠的应用:

  • Unix使用斜杆/ 作为路径分隔符,而web应用最新使用在Unix系统上面,所以目前所有的网络地址都采用 斜杆/ 作为分隔符。
  • Windows由于使用 斜杆/ 作为DOS命令提示符的参数标志了,为了不混淆,所以采用 反斜杠\作为路径分隔符。所以目前windows系统上的文件浏览器都是用 反斜杠\作为路径分隔符。随着发展,DOS系统已经被淘汰了,命令提示符也用的很少,斜杆和反斜杠在大多数情况下可以互换,没有影响。
  • 知道这个背景后,可以总结一下结论:

①浏览器地址栏网址使用 斜杆/ 。 ②windows文件浏览器上使用 反斜杠\或斜杠/,此外在Java字符串中表示时需用\\转义为\。 ③出现在html url() 属性中的路径,指定的路径是网络路径,所以必须用 斜杆/ ;同时这二者在充当路径分隔符时:

<div style="background-image:url(/Image/Control/title.jpg); background-repeat:repeat-x; padding:10px 10px 10px 10px"></div>
// 如果url后面用反斜杠,就不会显示任何背景

④出现在普通字符串中的路径,如果代表的是windows文件路径,则使用 斜杆/ 和 反斜杠\ 是一样的;如果代表的是网络文件路径,则必须使用 斜杆/ ;

<img src=".\Image/Control/ding.jpg" /> // 本地文件路径,/ 和 \ 是等效的
<img src="./Image\Control\cai.jpg" />
<img src="http://hiphotos.baidu.com/yuhua522/pic/item/01a949c67e1023549c163df2.jpg" /> // 网络文件路径,一定要使用 斜杆/

类加载器路径和类路径

类加载器路径简述:

  • ClassLoader为类加载器。
  • 它的方法有如下: 在这里插入图片描述
  • 这些需要传入一个路径的方法时。这个路径为一个相对路径。
  • 这个相对路径是相对于类加载器搜索.class文件的路径。
  • 也就是上面说到的idea的out中,ecplise的bin中。(普通Java项目中)
  • 也就是说我们将资源文件放在src中,(即相对于src编译后的路径)那么类加载器就可以找得到。
  • 此外如果在路径上加一个斜杠/则没有此路径。因为类加载器路径默认是一个根目录。
//获取相对路径为data.text的文件
URL resource = ClassLoader.getSystemClassLoader().getResource("data.text");
System.out.println(resource.getPath());

类路径简述:

  • 而如果是通过类调用则返回的当前类的路径。
  • 在通过类调用的路径上加斜杠/则返回当前类的根目录(也就是类加载器路径)。
//获取类的根路径 C:\Users\Shinelon\IdeaProjects\shangguigu\out\production\shangguigu
File f = new File(this.getClass().getResource("/").getPath());
System.out.println(f);

//获取类加载的路径 C:\Users\Shinelon\IdeaProjects\shangguigu\out\production\shangguigu\com\atguigu\examio
File files = new File(this.getClass().getResource("").getPath());
System.out.println(files);

总结:

  • getResource()方法和getResourceAsStream()方法: ①ClassLoader类同样拥有getResource()和getResourceAsStream()方法。 在这里插入图片描述 ②Class类和ClassLoader类同样拥有getResource()和getResourceAsStream()方法。 在这里插入图片描述getResource()方法可以获取指定路径并返回URL类型的对象。getResourceAsStream()方法可以获取指定路径并返回输入流对象。
  • 此外由于jvm中存在诸多类加载器如果直接调用ClassLoader类的getResourceAsStream()方法有可能存在调用类的加载器与ClassLoader类加载器不同的情况
  • 因此最好还是调用Class类的getClassLoader()方法获取本类的加载器再调用getResourceAsStream()方法方法或者直接调用Class类的getResourceAsStream()方法。
  • 此外ClassLoader类的getResourceAsStream()方法默认从classpath中找文件(文件放在resources目录下),name不能带“/”,否则会抛空指针。(因为本身就在类路径中,再加个/则变成磁盘目录了)
  • 而Class类的getResourceAsStream()方法。 ①如果name以"/"开头,那么绝对路径是/后边跟的名字。 ②如果name不是以"/"开头,那么绝对路径是package名"."换成“/”以后再加name,例如:com.abc.App就是/com/abc/App/name 。
public InputStream getResourceAsStream(String name) {
       name = resolveName(name);
       ClassLoader cl = getClassLoader0();
       if (cl==null) {
           // A system class.
           return ClassLoader.getSystemResourceAsStream(name);
       }
       return cl.getResourceAsStream(name);
}

Web工程路径

Web 工程和其编译结果的目录结构详解:

  • WEB-INF是Java的WEB应用的安全目录。所谓安全就是客户端无法访问,只有服务端可以访问的目录。

  • WebRoot其实是一个名字而已,在部署后是看不到的,访问的时候在url里肯定也是没有的,当然WebRoot也可以换成别WebContent或Web或WebApp等都可以。

  • JSP存放在WEB-INF 跟webroot的区别: ①放在webroot下面:优点,程序结构清晰,便于编码和维护;缺点,要加过滤器。 ②放在web-inf下面:优点,不用过滤器;缺点,打乱了程序结构,编码和维护麻烦点。

  • 静态资源存放在WEB-INF 跟webroot的区别: ①当静态资源放在webroot下面的时候,可直接通过浏览器访问,不需要配置映射,安全性略低。 ②当静态资源放在WEB-INF下面的时候,外部是不能直接访问的,一般是在springmvc的配置文件中配置资源映射。如:

    <!-- 资源映射 -->
    <mvc:resources location="/WEB-INF/css/" mapping="/css/**"/>
    <mvc:resources location="/WEB-INF/js/" mapping="/js/**"/>
  • jar包必须放到/WEB-INF/lib文件夹下。 ①tomcat应用服务器,它有其自己的类加载器,根据J2EE的规范去%web-project%/WEB-INF/lib的路径去找相应的lib下的jar文件。

Web 工程和其编译结果的目录结构对比见下图:

在这里插入图片描述

  • 其中src文件夹为源文件夹,项目中我们可以创建多个源文件夹而后编译后的位置都在WEB-INF下的classes文件夹下。
  • java工程和web工程编译区别: ①此外在项目根目录下创建的文件若没有设置为Sources roots或Resources Root则不会编译到Web工程目录(WebApp目录)中。而一般的java工程则在项目根目录下的文件都会被编译。
  • 注意: ①在普通java项目下.class(编译后的文件)是直接放在out(idea)/bin(ecplise)目录下的。 ②在web项目下.class(编译后的文件)是放在out目录下的工程名/WEB-INF/classes/中的。

Idea中其他文件和目录的作用:

  • out目录target目录的区别: ①out存放的是该项目下所有Module(也就是Project)的编译结果。 ②target存放的是单个Module的编译结果。
  • .iml文件 ①idea 对module 配置信息之意, infomation of module。iml是 intellij idea的工程配置文件,里面是当前module的一些配置信息。 ②iml文件是IntelliJ IDEA自动创建的模块文件,用于Java应用开发,存储一些模块开发相关的信息,比如一个Java组件,插件组件,Maven组件等等,还有可能会存储一些模块路径信息,依赖信息以及别的一些设置。
  • .idea文件夹 ①idea存放项目的配置信息,包括历史记录,版本控制信息等

路径总结

相对路径和绝对路径:

  • 绝对路径:http://ip:port/工程名/资源路径。
  • 相对路径: ①. /文件名 表示当前文件所在目录 ②../文件名 表示当前文件所在上级目录 ③文件名 表示当前文件所在目录的文件,相当于./文件名 ./可以省略
  • 上述相对路径的语法只在HTML中有效,对于在Java或者XML配置文件(底层还是被Java解析)中是无效的,虽然开发中在XML配置文件中看起来有效(语法特性生效),但一运行会报错。

classpath和file加载文件的区别(仅在框架中使用):

  • file:加载非编译类的文件系统,即:作为 URL 从文件系统中加载,而非classes文件夹下的。 ①可以直接成从盘符写起,则写成E:\IdeaWork\ssm-crud\src\main\resources\mapper\aa\mybatisConfig.xml ②从当前项目所在盘符后的目录写起,则写成\IdeaWork\ssm-crud\src\main\resources\mapper\aa\mybatisConfig.xml(加斜杠/) ③从当前项目路径写起,则写成src/main/resources/mybatisConfig.xml(不加斜杠/) ③总结来说和JAVA的IO一样,而JavaIO包中是相对于当前用户目录来分析相对路径的,因此想在class文件系统中使用必须写绝对路径。此外由于是在文件系统中,可以写成单斜杠/,单反斜杠\,以及双反斜杠\\
  • classpath:加载编译的class文件系统,(即classes文件夹下)。 ①即:从classpath中加载。(开头带不带斜杠/都无所谓
  • classpath*:加载编译的class文件系统,(即classes文件夹下)。 ①不仅包含class路径,还包括jar文件中(class路径)进行查找,而且不仅限于classes当前目录下,也会对其子目录进行搜索。(开头带不带斜杠/都无所谓
  • none在当前文件目录下加载。 ①例如:配置文件在/resourses下,要想配置位于/resourses/dbfile/mybatis.config,则直接写成/dbfile/mybatis.config(加斜杠)。(也可以不加斜杠dbfile/mybatis.config)在这里插入图片描述

服务端路径:

  • 服务端路径是指在服务器上面运行的请求,比如请求转发(常用)、请求包含等。
  • 注意:服务器端的路径不能是绝对路径,只能是相对路径。
  • 服务端的路径有两种:相对于当前应用的路径和相对于当前请求的路径。
  • 以"/"开头的相对路径 ,此时"/"代表当前web项目,即:http://localhost:8080/javaee
  • 不以"/"开头的相对路径则表示相对于当前资源的相对路径 ,若此时当前资源的路径为:http://localhost:8080/javaee/DispatcherServlet ,则要转发的路径以http://localhost:8080/javaee开头。

客户端路径:

资源获取路径:

  • 获取资源的路径主要有3种,分别是ServletContextClassClassLoader
  • 其中ServletContext是WEB阶段的,Tomcat提供的一种获取资源的方式。
  • Class和ClassLoader获取资源主要是JavaAPI提供的一种获取流的方式。(上面已讲)
  • 这里ServletContext获取资源的路径是相对项目的绝对路径。
  • 基本语法: ①servletContext.getRealPath("路径"); ②参数中的路径必须是相对路径,传入的参数是从当前servlet 部署在tomcat中的文件夹算起的相对路径,加不加“/”无所谓
  • 另外获取ServletContext的方法如下: ①使用request获取: request.getSession().getServletContext(); ②在Servlet中获取:this.getServletContext(); ③使用FilterConfig对象获取(在Filter中使用):config.getServletContext();
  • 注意:ServletContext获取资源必须是相对路径,不能是绝对路径,但不管是以/开头,还是不以/开头, 都是相对于当前资源的相对路径 。

路径中*和**的区别与路径分类:

  • 链接:路径详解
  • 路径分为前缀(路径型)路径扩展名(后缀型)路径。 ①前缀路径举例:/psotEmp,/emp ②扩展名路径举例:/index.jsp,/empList.html
  • 拦截请求中: ①/ 拦截所有请求 包括静态资源和动态请求 但是不拦截jsp/*拦截所有请求 包括静态资源和动态请求 也拦截jsp*.XX以XX结尾的路径如*.html匹配index.html。
  • @RequestMapping 还支持Ant 风格资源地址支持 3 种匹配符: ①?:匹配文件名中的一个字符*:匹配文件名中的任意字符** :匹配多层路径
  • mybatis和maven和spring和springMVC配置文件中: ①*:匹配所有文件夹,不含子文件夹**:匹配所有文件夹及里面的子文件夹

总结:

  • 客户端是带“/”相对当前主机。
  • 服务端(包括上述的服务端、url-pattern路径和ServletContext路径)带“/”都是相对当前应用,不带“/”则是当前应用中的当前位置。
  • Class带“/”是相对当前类路径。不带“/”是相对于当前位置。 <1>调用类的加载器从加载类的搜索路径中获取资源
  • ClassLoader无论不带“/”都是当前类路径,带“/”则为null。 <1>默认是通过系统类加载器从加载类的搜索路径中获取资源
  • 因此如果在Demo中使用ClassLoader.getSystemResourceAsStream()还是可以用的,但是如果作为一个web项目启动的话,就有点问题了。因为Web服务器不一定使用系统类加载器去加载,而使用Class.getResourceAsStream()则默认跟随服务器的加载器
  • 路径详解