JAVA文件中获取路径及WEB应用程序获取路径方法

JAVA文件中获取路径及 web 应用程序获取路径方法


1. 基本概念的理解

绝对路径:你应用上的文件或目录在硬盘上真正的路径,如:URL、物理路径

例如:

c:/xyz/test.txt 代表了 test.txt 文件的绝对路径;

http://www.sun.com/index.htm 代表了一个 URL 绝对路径;

相对路径:相对与某个基准目录的路径,包含 web 的相对路径(HTML 中的相对目录)

例如:

在 Servlet 中,”/” 代表 web 应用的根目录,和物理路径的相对表示;

“./”代表当前目录,”../”代表上级目录。这种类似的表示,也是属于相对路径;

2. 关于 JSP/Servlet 中的相对路径和绝对路径

2.1 服务器端的地址

服务器端的相对地址指的是相对于你的 web 应用的地址,这个地址是在服务器端解析的(不同于 html 和 javascript 中的相对地址,他们是由客户端浏览器解析的)也就是说这时候在 jsp 和 servlet 中的相对地址应该是相对于你的 web 应用,即相对于 http://192.168.0.1/ web app/ 的。

其用到的地方有:

forward:servlet 中的 request.getRequestDispatcher(address); 这个 address 是在服务器端解析的,所以,你要 forward 到 a.jsp 应该这么写:
request.getRequestDispatcher(“/user/a.jsp”) 这个 / 相对于当前的 web 应用 web app,其绝对地址就是:http://192.168.0.1/ web app/user/a.jsp。

2.2 客户端的地址

所有的 html 页面中的相对地址都是相对于服务器根目录( http://192.168.0.1/ )的,而不是(根目录下的该 web 应用的目录) http://192.168.0.1/ web app/ 的。

Html 中的 form 表单的 action 属性的地址应该是相对于服务器根目录 (http://192.168.0.1/) 的,所以,如果提交到 a.jsp 为:action=”/ web app/user/a.jsp” 或 action=”/user/a.jsp”,提交到 servlet 为 action=”/ web app/handleservlet”。

Javascript 也是在客户端解析的,所以其相对路径和 form 表单一样。

因此,一般情况下,在 JSP/HTML 页面等引用的 CSS,Javascript,Action 等属性前面最好都加上 web app 应用名称,以确保所引用的文件都属于 web 应用中的目录。

另外,应该尽量避免使用类似”.”,”./”,”../../” 等类似的相对该文件位置的相对路径,这样当文件移动时,很容易出问题。

3. JSP/Servlet 中获得当前应用的相对路径和绝对路径

3.1 JSP 中获得当前应用的相对路径和绝对路径

根目录所对应的绝对路径:request.getRequestURI();

文件的绝对路径:application.getRealPath(request.getRequestURI());

当前 web 应用的绝对路径:application.getRealPath(“/”);

取得请求文件的上层目录:
newFile(application.getRealPath(request.getRequestURI())).getParent();

3.2 Servlet中获得当前应用的相对路径和绝对路径

根目录所对应的绝对路径:request.getServletPath();

文件的绝对路径:request.getSession().getServletContext().getRealPath();

当前 web 应用的绝对路径:servletConfig.getServletContext().getRealPath(“/”);

ServletContext对象获得几种方式:

javax.servlet.http.HttpSession.getServletContext()
javax.servlet.jsp.PageContext.getServletContext()
javax.servlet.ServletConfig.getServletContext()

4. java的Class中获得相对路径,绝对路径的方法

4.1 单独的Java类中获得绝对路径

根据java.io.File的Doc文挡,可知:默认情况下newFile(“/”)代表的目录为:System.getProperty(“user.dir”);。

以下程序获得执行类的当前路径:

package org.cheng.file; 
import java.io.File; 
public class FileTest{ 
    public static void main(String[]args)throws Exception{ 
        System.out.println(Thread.currentThread().getContextClassLoader().getResource("")); 
        System.out.println(FileTest.class.getClassLoader().getResource("")); 
        System.out.println(ClassLoader.getSystemResource("")); 
        System.out.println(FileTest.class.getResource("")); 
        // Class文件所在路径 
        System.out.println(FileTest.class.getResource("/"));
        System.out.println(newFile("/").getAbsolutePath()); 
        System.out.println(System.getProperty("user.dir")); 
    } 
}
4.2 服务器中的 Java 类获得当前路径

1. web logic

web Application 的系统文件根目录是你的 web logic 安装所在根目录。

例如:如果你的 web logic 安装在 c:ea web logic700…..

那么,你的文件根路径就是 c:.

所以,有两种方式能够让你访问你的服务器端的文件:

a.使用绝对路径

比如将你的参数文件放在 c:yourconfig/yourconf.properties,

直接使用 newFileInputStream(“yourconfig/yourconf.properties”);

b.使用相对路径

相对路径的根目录就是你的 web application 的根路径,即 web -INF 的上一级目录,将你的参数文件放在 your web app/yourconfig/yourconf.properties,

这样使用:

newFileInputStream(“./yourconfig/yourconf.properties”);

2. Tomcat

在类中输出 System.getProperty(“user.dir”); 显示的是 %Tomcat_Home%/bin

如何读相对路径?

在 Java 文件中 getResource 或 getResourceAsStream 均可

例:getClass().getResourceAsStream(filePath);
filePath可以是 “/filename”,这里的 / 代表 web 发布根路径下 web -INF/classes

默认使用该方法的路径是: web -INF/classes。已经在 Tomcat 中测试。

5. 读取文件时的相对路径,避免硬编码和绝对路径的使用

5.1 采用Spring的DI机制获得文件,避免硬编码

Java 中使用的路径,分为两种:绝对路径和相对路径。具体而言,又分为四种:

(1) URI 形式的绝对资源路径

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

URL 是 URI 的特例。URL 的前缀 / 协议,必须是 Java 认识的。
URL 可以打开资源,而 URI 则不行。

URL 和 URI 对象可以互相转换,使用各自的 toURI() ,toURL() 方法即可!

(2) 本地系统的绝对路径

D:/java/eclipse32/workspace/jbpmtest3/bin/aaa.b

Java.io包中的类,需要使用这种形式的参数。但是,它们一般也提供了 URI 类型的参数,而 URI 类型的参数,接受的是 URI 样式的 String。因此,通过 URI 转换,还是可以把 URI 样式的绝对路径用在 java.io 包中的类中。

(3) 相对于 classpath 的相对路径

如:相对于 file:/D:/java/eclipse32/workspace/jbpmtest3/bin/ 这个路径的相对路径。其中,bin 是本项目的 classpath。所有的 Java 源文件编译后的 .class文件复制到这个目录中。

(4) 相对于当前用户目录的相对路径

就是相对于 System.getProperty(“user.dir”) 返回的路径。

对于一般项目,这是项目的根路径。对于JavaEE服务器,这可能是服务器的某个路径。这个并没有统一的规范!

所以,绝对不要使用“相对于当前用户目录的相对路径”。

然而:默认情况下,java.io 包中的类总是根据当前用户目录来分析相对路径名。此目录由系统属性 user.dir 指定,通常是 Java 虚拟机的调用目录。

这就是说,在使用 java.io 包中的类时,最好不要使用相对路径。否则,虽然在J2SE 应用程序中可能还算正常,但是到了 J2EE 程序中,一定会出问题!而且这个路径,在不同的服务器中都是不同的!

相对路径最佳实践:推荐使用相对于当前classpath的相对路径,因此,我们在使用相对路径时,应当使用相对于当前classpath的相对路径。

ClassLoader 类的 getResource(String name), getResourceAsStream(String name) 等方法 ,使用相对于当前项目的classpath的相对路径来查找资源。

读取属性文件常用到的 ResourceBundle 类的 getBundle(String path) 也是如此。

通过查看 ClassLoader 类及其相关类的源代码,它实际上还是使用了 URI 形式的绝对路径。通过得到当前 classpath 的 URI 形式的绝对路径,构建了相对路径的 URI 形式的绝对路径。(这个实际上是猜想,因为 JDK 内部调用了 SUN 的源代码,而这些代码不属于 JDK,不是开源的)

相对路径本质上还是绝对路径,因此,归根结底,Java 本质上只能使用绝对路径来寻找资源。所有的相对路径寻找资源的方法,都不过是一些便利方法。不过是 API 在底层帮助我们构建了绝对路径,从而找到资源的!

下面是一些得到 classpath 和当前类的绝对路径的一些方法,你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。

1、FileTest.class.getResource(“”):得到的是当前类 FileTest.class 文件的 URI目录。不包括自己!

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/com/test/

2、 FileTest.class.getResource(“/”):得到的是当前的 classpath 的绝对 URI 路径。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

3、 Thread.currentThread().getContextClassLoader().getResource(“”):得到的也是当前 ClassPath 的绝对 URI 路径。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

4、FileTest.class.getClassLoader().getResource(“”):得到的也是当前 ClassPath 的绝对 URI 路径。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

5、ClassLoader.getSystemResource(“”):得到的也是当前 ClassPath 的绝对 URI 路径。

如:file:/D:/java/eclipse32/workspace/jbpmtest3/bin/

推荐使用:Thread.currentThread().getContextClassLoader().getResource(“”) 来得到当前的 classpath 的绝对路径的 URI 表示法。

5.2 web 应用程序中资源的寻址

上文中说过,当前用户目录,即相对于 System.getProperty(“user.dir”) 返回的路径。对于 JavaEE 服务器,这可能是服务器的某个路径,这个并没有统一的规范!而不是我们发布的 web 应用程序的根目录!这样,在 web 应用程序中,我们绝对不能使用相对于当前用户目录的相对路径。

在 web 应用程序中,我们一般通过 ServletContext.getRealPath(“/”) 方法得到 web 应用程序的根目录的绝对路径。这样,我们只需要提供相对于 web 应用程序根目录的路径,就可以构建出定位资源的绝对路径。

这是我们开发 web 应用程序时一般所采取的策略。

Classpath 外配置文件读取问题

如,我们使用测试驱动开发的方法,开发 Spring、Hibernate、iBatis 等使用配置文件的 web 应用程序,就会遇到问题。

尽管 Spring 自己提供了 FileSystem(也就是相对于user.dir目录)来读取 web 配置文件的方法,但是终究不是很方便。而且与 web 程序中的代码使用方式不一致!

至于 Hibernate,iBatis 就更麻烦了!只有把配置文件移到 classpath 下,否则根本不可能使用测试驱动开发!

通用的相对路径解决办法

面对这个问题,编写一个助手类 ClassLoaderUtil ,提供一个便利方法 [public static URL getExtendResource(String relativePath)]。在 web 应用程序等一切 Java 程序中,需要定位 classpath 外的资源时,都使用这个助手类的便利方法,而不使用 web 应用程序特有的 ServletContext.getRealPath(“/”) 方法来定位资源。

利用 classpath 的绝对路径,定位所有资源

这个便利方法的实现原理,就是“利用 classpath 的绝对路径,定位所有资源”。

ClassLoader 类的 getResource(“”) 方法能够得到当前 classpath 的绝对路径,这是所有Java程序都拥有的能力,具有最大的适应性!

而目前的JDK提供的 ClassLoader 类的 getResource(String 相对路径) 方法,只能接受一般的相对路径。这样,使用 ClassLoader 类的 getResource(String 相对路径)方法就只能定位到 classpath 下的资源。

如果,它能够接受“../”这样的参数,允许我们用相对路径来定位 classpath 外面的资源,那么我们就可以定位位置的资源!

当然,我无法修改 ClassLoader 类的这个方法,于是,我编写了一个助手类 ClassLoaderUtil 类,提供了[public static URL getExtendResource(String relativePath)]这个方法。它能够接受带有“../”符号的相对路径,实现了自由寻找资源的功能。




原文:
JAVA 文件中获取路径及 web 应用程序获取路径方法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java ,MultipartFile 是 Spring 框架提供的一个接口,用于处理上传的文件。由于 MultipartFile 是对上传的文件内容进行封装的,而不是直接提供文件路径,因此无法直接获取文件路径。 如果你想要获取上传文件路径,可以借助其他方法来实现。一个常见的方式是将上传的文件保存到指定的目录,然后获取目录下的文件路径。 下面是一个示例代码,展示了如何通过 MultipartFile 将文件保存到指定目录获取文件路径: ```java import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; public class FileUploadService { public String saveFile(MultipartFile file) throws IOException { // 指定保存文件目录 String uploadDir = "/path/to/upload/dir"; // 如果目录不存在则创建 File dir = new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } // 获取上传文件的原始名称 String originalFilename = StringUtils.cleanPath(file.getOriginalFilename()); // 生成保存文件路径 String filePath = uploadDir + File.separator + originalFilename; // 保存文件 file.transferTo(new File(filePath)); return filePath; } } ``` 在上述示例,`saveFile` 方法接收一个 MultipartFile 对象作为参数。它首先指定了一个保存文件目录 `uploadDir`,然后将上传文件的原始名称通过 `StringUtils.cleanPath` 方法进行处理,生成最终的保存路径 `filePath`。最后,通过调用 `transferTo` 方法文件保存到指定路径。 请根据你的实际需求修改目录路径和其他相关逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值