Java 从 Spring Boot 中的资源文件夹中读取文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44399422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read file from resources folder in Spring Boot
提问by g3blv
I'm using Spring Boot and json-schema-validator
. I'm trying to read a file called jsonschema.json
from the resources
folder. I've tried a few different ways but I can't get it to work. This is my code.
我正在使用 Spring Boot 和json-schema-validator
. 我正在尝试读取jsonschema.json
从resources
文件夹中调用的文件。我尝试了几种不同的方法,但无法正常工作。这是我的代码。
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);
This is the location of the file.
这是文件的位置。
And here I can see the file in the classes
folder.
在这里我可以看到文件classes
夹中的文件。
But when I run the code I get the following error.
但是当我运行代码时,出现以下错误。
jsonSchemaValidator error: java.io.FileNotFoundException: /home/user/Dev/Java/Java%20Programs/SystemRoutines/target/classes/jsonschema.json (No such file or directory)
What is it I'm doing wrong in my code?
我在代码中做错了什么?
回答by povisenko
Very short answer: you are looking for your property in the scope of a particular class loader instead of you target class. This should work:
非常简短的回答:您正在特定类加载器的范围内寻找您的属性,而不是您的目标类。这应该有效:
File file = new File(getClass().getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);
Also, see this:
另外,请看这个:
- What is the difference between Class.getResource() and ClassLoader.getResource()?
- Strange behavior of Class.getResource() and ClassLoader.getResource() in executable jar
- Loading resources using getClass().getResource()
- Class.getResource() 和 ClassLoader.getResource() 有什么区别?
- 可执行 jar 中 Class.getResource() 和 ClassLoader.getResource() 的奇怪行为
- 使用 getClass().getResource() 加载资源
P.S. there can be an issue if the project has been compiled on one machine and after that has been launched on another or you run your app in Docker. In this case, paths to your resource folder can be invalid. In this case it would be better to determine paths to your resources at runtime:
PS 如果项目已在一台机器上编译,然后在另一台机器上启动,或者您在 Docker 中运行您的应用程序,则可能会出现问题。在这种情况下,资源文件夹的路径可能无效。在这种情况下,最好在运行时确定资源的路径:
ClassPathResource res = new ClassPathResource("jsonschema.json");
File file = new File(res.getPath());
JsonNode mySchema = JsonLoader.fromFile(file);
Update from 2020
2020 年更新
On top of that if you want to read resource file as a String in your tests, for example, you can use these static utils methods:
最重要的是,如果您想在测试中将资源文件作为字符串读取,例如,您可以使用这些静态 utils 方法:
public static String getResourceFileAsString(String fileName) {
InputStream is = getResourceFileAsInputStream(fileName);
if (is != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
return (String)reader.lines().collect(Collectors.joining(System.lineSeparator()));
} else {
throw new RuntimeException("resource not found");
}
}
public static InputStream getResourceFileAsInputStream(String fileName) {
ClassLoader classLoader = {CurrentClass}.class.getClassLoader();
return classLoader.getResourceAsStream(fileName);
}
Example of usage:
用法示例:
String soapXML = getResourceFileAsString("some_folder_in_resources/SOPA_request.xml");
回答by Govind Singh
stuck in the same issue, this helps me
陷入同样的问题,这对我有帮助
URL resource = getClass().getClassLoader().getResource("jsonschema.json");
JsonNode jsonNode = JsonLoader.fromURL(resource);
回答by John
After spending a lot of time trying to resolve this issue, finally found a solution that works. The solution makes use of Spring's ResourceUtils. Should work for json files as well.
在花了很多时间试图解决这个问题之后,终于找到了一个有效的解决方案。该解决方案利用了 Spring 的 ResourceUtils。也应该适用于 json 文件。
Thanks for the well written page by Lokesh Gupta : Blog
感谢 Lokesh Gupta 写得很好的页面:博客
package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;
public class Utils {
private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());
public static Properties fetchProperties(){
Properties properties = new Properties();
try {
File file = ResourceUtils.getFile("classpath:application.properties");
InputStream in = new FileInputStream(file);
properties.load(in);
} catch (IOException e) {
LOGGER.error(e.getMessage());
}
return properties;
}
}
To answer a few concerns on the comments :
回答一些对评论的关注:
Pretty sure I had this running on Amazon EC2 using java -jar target/image-service-slave-1.0-SNAPSHOT.jar
很确定我在 Amazon EC2 上运行了这个 java -jar target/image-service-slave-1.0-SNAPSHOT.jar
Look at my github repo : https://github.com/johnsanthosh/image-serviceto figure out the right way to run this from a JAR.
查看我的 github 存储库:https: //github.com/johnsanthosh/image-service找出从 JAR 运行它的正确方法。
回答by MostafaMashayekhi
create json folder in resources as subfolder then add json file in folder then you can use this code :
在资源中创建 json 文件夹作为子文件夹,然后在文件夹中添加 json 文件,然后您可以使用以下代码:
import com.fasterxml.Hymanson.core.type.TypeReference;
import com.fasterxml.Hymanson.core.type.TypeReference;
InputStream is = TypeReference.class.getResourceAsStream("/json/fcmgoogletoken.json");
InputStream is = TypeReference.class.getResourceAsStream("/json/fcmgoogletoken.json");
this works in Docker.
这适用于 Docker。
回答by Ismail
if you have for example config folder under Resources folder I tried this Class working perfectly hope be useful
如果您在 Resources 文件夹下有例如 config 文件夹,我试过这个类工作得很好,希望有用
File file = ResourceUtils.getFile("classpath:config/sample.txt")
//Read File Content
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);
回答by Er?in Ak?ay
Here is my solution. May help someone;
这是我的解决方案。可能会帮助某人;
It returns InputStream, but i assume you can read from it too.
它返回 InputStream,但我假设您也可以从中读取。
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jsonschema.json");
回答by sajal rajabhoj
See my answer here: https://stackoverflow.com/a/56854431/4453282
在此处查看我的答案:https: //stackoverflow.com/a/56854431/4453282
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
Use these 2 imports.
使用这两个进口。
Declare
宣布
@Autowired
ResourceLoader resourceLoader;
Use this in some function
在某些功能中使用它
Resource resource=resourceLoader.getResource("classpath:preferences.json");
In your case, as you need the file you may use following
在您的情况下,根据您的需要,您可以使用以下文件
File file = resource.getFile()
File file = resource.getFile()
Reference:http://frugalisminds.com/spring/load-file-classpath-spring-boot/As already mentioned in previous answers don't use ResourceUtils it doesn't work after deployment of JAR, this will work in IDE as well as after deployment
参考:http: //frugalisminds.com/spring/load-file-classpath-spring-boot/正如前面的答案中已经提到的,不要使用 ResourceUtils 它在部署 JAR 后不起作用,这也适用于 IDE部署后
回答by Emmanuel Osimosu
Spent way too much time coming back to this page so just gonna leave this here:
花了太多时间回到这个页面,所以就把这个留在这里:
File file = new ClassPathResource("data/data.json").getFile();
回答by Bhaumik Thakkar
Below is my working code.
下面是我的工作代码。
List<sampleObject> list = new ArrayList<>();
File file = new ClassPathResource("json/test.json").getFile();
ObjectMapper objectMapper = new ObjectMapper();
sampleObject = Arrays.asList(objectMapper.readValue(file, sampleObject[].class));
Hope it helps one!
希望对大家有所帮助!
回答by Vijayakumar S
For me, the bug had two fixes.
对我来说,这个错误有两个修复。
- Xml file which was named as SAMPLE.XML which was causing even the below solution to fail when deployed to aws ec2. The fix was to rename it to new_sample.xml and apply the solution given below.
- Solution approach https://medium.com/@jonathan.henrique.smtp/reading-files-in-resource-path-from-jar-artifact-459ce00d2130
- 名为 SAMPLE.XML 的 Xml 文件在部署到 aws ec2 时甚至会导致以下解决方案失败。修复方法是将其重命名为 new_sample.xml 并应用下面给出的解决方案。
- 解决方法 https://medium.com/@jonathan.henrique.smtp/reading-files-in-resource-path-from-jar-artifact-459ce00d2130
I was using Spring boot as jar and deployed to aws ec2 Java variant of the solution is as below :
我使用 Spring boot 作为 jar 并部署到 aws ec2 Java 变体的解决方案如下:
package com.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
public class XmlReader {
private static Logger LOGGER = LoggerFactory.getLogger(XmlReader.class);
public static void main(String[] args) {
String fileLocation = "classpath:cbs_response.xml";
String reponseXML = null;
try (ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext()){
Resource resource = appContext.getResource(fileLocation);
if (resource.isReadable()) {
BufferedReader reader =
new BufferedReader(new InputStreamReader(resource.getInputStream()));
Stream<String> lines = reader.lines();
reponseXML = lines.collect(Collectors.joining("\n"));
}
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
}