常识——java的getResource获取不到真实路径

本文探讨了Java项目中资源文件的路径问题,解释了为何需要将java目录设为source root来识别XML文件,以及IDEA与Tomcat部署时路径变化的原因。还分析了类与类加载器加载资源文件的区别,并介绍了Spring如何通过注解加载配置文件。
摘要由CSDN通过智能技术生成

前言

因为在idea编辑器上和被tomcat实际部署中,资源文件的路径实际是不同的,所以常常使用getResource来动态获取资源文件的真实地址,TestJsoup.class.getClassLoader().getResource("SimpleTest.xml").getPath(),例如此
然而有时却发现获取到的是空值,这是为什么呢?

解决

如图所示,应该将资源文件xml放置在src/java路径下,然后java目录设置为source root,创建资源文件夹resource,将xml放进去这样才能识别到
为什么会有这样的放置xml的规则呢?
因为xml文件在idea中读写和部署到tomcat时遵循了两种文件放置规则,也就是各自规定了一套文件路径规则,路径发生了变化,如果不这样设置,部署时就会发现找不到这个文件
在这里插入图片描述

resource路径也需要定义
在这里插入图片描述

为什么需要将java目录变成source root类型才能识别到下面的xml文件呢?

.class 是获取当前类的 class 对象,getClassLoader()是获取当前的类加载器
类加载器可以将class文件加载到内存中,并创建一个类对象,getResource是用来获取类的资源的
而获取资源的默认路径就是类所在的路径,即是classPath,将src变成souce root文件类型,就当作类的开始路径了
因为每个类是不同的,虽然存在父子关系,然而并没有什么用,“子知道父,父不知道子”,不同的类加载器是无法相互访问的,这里使用当前类的加载器加载资源文件也是保证他们被同一个类加载器加载,这样 当前类就能够访问同样被同一个类加载器加载的资源文件了

为什么idea上放好的路径,被tomcat部署之后路径就变了呢?

这是因为idea和tomcat对于工程文件的管理方式不同 ,各自制定了一套文件放置规则
最初,由Maven构建的web工程,主代码放在src/main/java路径下,资源放在src/main/resources路径下
然后
JavaWeb项目部署服务器时会将项目打包成Jar包或者war包,此时就不会存在 src/main/resources,也没有java 目录,JVM会在编译项目时,主动将 java文件编译成 class文件 并将与 resources 下的静态文件一并放在 target/classes目录下;
如图,java文件都编译成了class文件,资源文件都被复制了一份一并放到了target/classes目录,使用的是tomcat文件放置规则
在这里插入图片描述

有趣的是,在idea上,本地运行时
Java文件编译成 class文件被JVM执行,当前项目即为Java进程的工作空间,虽然class文件在target/classes目录下,但是target/classes不是class文件运行的目录,只是存放的目录,运行目录还是在IDEA的模块下,所以运行时会找到 src/main/resources 资源文件。 使用的是本地文件放置规则

类与它的类加载器都可以加载资源文件,区别是什么?

class.getClassLoader().getResourceAsStream() 和 class.getResouceAsStream() 的区别
a)class.getClassLoader().getResourceAsStream(String name) 默认从classpath中找文件(文件放在resources目录下),name不能带"/“,否则会抛空指针。采用相对路径, “/“就相当于当前进程的根目录,即项目根目录;
inStream = PropertiesTest.class.getClassLoader().getResourceAsStream(“com/test/demo/test.properties”);
意思是从src下找文件
b)class.getResourceAsStream(String name) 是采用绝对路径,绝对路径是相对于 classpath 根目录的路径,”/” 就代表着 classpath,所以 name 属性需要前面加上 “/”;
inStream = PropertiesTest.class.getResourceAsStream(”/com/test/demo/test.properties")
意思是从项目根路径开始找文件

spring注解加载配置文件

写资源文件加载代码那是很久以前了,现在都是注解,@一下自动配置
如果工程中使用Spring,可以通过注解的方式获取配置信息,但需要将配置文件放到Spring配置文件中扫描后,才能将配置信息放入上下文。

 <context:component-scan base-package="com.xxxx.service"/>
 <context:property-placeholder location="classpath:properties/xxx.properties" ignore-unresolvable="true"/>

然后在程序中可以使用 @Value进行获取properties文件中的属性值,如下:

 @Value("${xxxt.server}")
 private static String serverUrl;

采用Spring配置

也可以在Spring配置文件中读取属性值,赋予类成员变量

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
      
      <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="location" value="classpath:properties/xxx.properties"/>
      </bean>
     
     <bean id="service" class="com.xxxx.service.ServiceImpl">         <property name="serverUrl" value="${xxxt.server}" />
     </bean>
 
 </beans>

SpringBoot项目启动后,动态的读取类路径下文件数据

InputStream inputStream = EncryptUtil.class.getResourceAsStream("/HelloServiceEncryptFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine();

// 获取类路径下的文件路径
File path = new File(ResourceUtils.getURL("classpath:").getPath());
if (!path.exists()) {
   path = new File("");
}
log.info("path = {}", path.getAbsolutePath());
File upload = new File(path.getAbsolutePath(), "com/study/service");
if (!upload.exists()) {
    upload.mkdirs();
}
FileOutputStream fos = new FileOutputStream(upload.getAbsolutePath() + File.separator + "hello.txt");
IoUtil.copy(inputStream, fos);
fos.close();
inputStream.close();
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: A:可以使用以下代码获取resource下特定文件夹的路径: ``` String folderPath = getClass().getClassLoader().getResource("folderName").getPath(); ``` 其中,"folderName"为要获取路径文件夹名称。需要注意的是,路径中可能会包含特殊字符,需要进行转义或解码操作。 ### 回答2: Java获取resource文件路径可以通过以下方法实现: 1. 使用Class.getResource()方法: ``` String folderPath = MyClass.class.getResource("/folderName").getPath(); ``` 2. 使用ClassLoader.getResource()方法: ``` String folderPath = MyClass.class.getClassLoader().getResource("folderName").getPath(); ``` 其中,`folderName`表示resource下的文件夹名称。这两种方法都可以获得文件夹的绝对路径。 需要注意的是,通过getResource()方法获取路径会将空格转义为"%20",如果需要使用路径时,可以通过URLDecoder.decode()方法将其转换回来。 另外,在使用getResource()方法时,需要注意路径的写法。一般来说,使用相对路径即可,但如果需要指定resource文件夹的根目录,则需要使用绝对路径,以"/"开头。 通过以上方法,就可以在Java获取resource文件夹的路径了。 ### 回答3: 在Java中,要获取resource文件夹的路径,可以使用以下方法: ```java ClassLoader classLoader = getClass().getClassLoader(); URL resourceUrl = classLoader.getResource("文件路径"); ``` 其中,文件路径是相对于resource文件夹的相对路径,可以使用斜杠(/)分隔不同层级的文件夹。 如果要获取resource文件夹下的名为"folder"的文件夹的路径,可以使用以下代码: ```java ClassLoader classLoader = getClass().getClassLoader(); URL resourceUrl = classLoader.getResource("folder"); ``` 注意,此代码段假设当前类在类路径中能够找到,如果在静态方法中使用,需要将getClass()更换为具体的类名。 以上代码会返回一个URL对象,可以通过调用其getPath()方法获取resource文件夹下文件夹的路径字符串。 ```java String folderPath = resourceUrl.getPath(); ``` 需要注意的是,在某些情况下获取路径可能包含空格或其他特殊字符,需要做相应处理。 此外,如果要获取文件夹下的具体文件路径,可以使用以下代码: ```java String folderPath = resourceUrl.getPath(); File folder = new File(folderPath); String[] fileNames = folder.list(); for (String fileName : fileNames) { String filePath = folderPath + File.separator + fileName; // 处理文件路径 } ``` 以上是获取resource文件路径的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值