在Spring Boot中从资源文件夹读取文件


81

我正在使用Spring Boot和json-schema-validator。我正在尝试jsonschema.jsonresources文件夹读取一个文件。我尝试了几种不同的方法,但无法正常工作。这是我的代码。

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);

这是文件的位置。

在此处输入图片说明

在这里,我可以看到文件classes夹中的文件。

在此处输入图片说明

但是,当我运行代码时,出现以下错误。

jsonSchemaValidator error: java.io.FileNotFoundException: /home/user/Dev/Java/Java%20Programs/SystemRoutines/target/classes/jsonschema.json (No such file or directory)

我在代码中做错了什么?


你可以试试这个吗?ClassLoader classLoader = getClass().getClassLoader(); JsonNode mySchema = JsonLoader.getJson(classLoader.getResourceAsStream("jsonschema.json"));
harshavmb

Answers:


86

在花费大量时间尝试解决此问题之后,终于找到了可行的解决方案。该解决方案利用了Spring的ResourceUtils。应该也适用于json文件。

感谢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;
    }
}

要回答有关评论的一些问题:

相当确定我已经使用以下命令在Amazon EC2上运行了它 java -jar target/image-service-slave-1.0-SNAPSHOT.jar

查看我的github存储库:https : //github.com/johnsanthosh/image-service, 以找出从JAR运行此代码的正确方法。


1
感谢约翰添加此内容。使用ResourceUtil可以有效并且肯定是更好的方法。
阿塔尔

1
@Athar Glad我可以提供帮助。
约翰·约翰(John

37
仅当您尝试从IDE运行应用程序时,此方法才有效,但是当您运行jar时,找不到适合您的文件。
哈桑·穆达西

9
同意Hassan,new ClassPathResource("filename").getInputStream()如果从jar运行应用程序,则应该使用。细节
Jingchao Luan

2
同意哈桑。需要注意的是,ResourceUtils Javadoc很清楚该类主要供内部使用。检查以及stackoverflow.com/questions/25869428/...
埃里克·江

30

非常简短的答案:您正在特定类加载器的范围内寻找属性,而不是目标类。这应该工作:

File file = new File(getClass().getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);

另外,请参阅以下内容:

PS:如果项目已在一台计算机上编译,然后在另一台计算机上启动,或者您在Docker中运行应用程序,则可能会出现问题。在这种情况下,资源文件夹的路径可能无效。在这种情况下,最好在运行时确定资源的路径:

ClassPathResource res = new ClassPathResource("jsonschema.json");    
File file = new File(res.getPath());
JsonNode mySchema = JsonLoader.fromFile(file);

2020年更新

最重要的是,例如,如果您想在测试中以字符串形式读取资源文件,则可以使用以下静态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);
}

用法示例:

String soapXML = getResourceFileAsString("some_folder_in_resources/SOPA_request.xml");

2
getClass().getResource("jsonschema.json")返回null。我也试过ClassPathResource res = new ClassPathResource("jsonschema.json")只是返回jsonschema.json。这与我使用Spring Boot有关吗?
g3blv

关于getClass().getResource("jsonschema.json")回报的@ g3blvnull我可以参考这个主题stackoverflow.com/questions/26328040/…。最重要的是,尝试重建您的项目。反馈将不胜感激。
povis

@ g3blv我提供了最新的答案,请查看
povis

1
@povisenko我建议您如果为is空则抛出异常。这意味着您要查找的文件/资源​​不存在。
endertunc

完整的答案。在IDE和jar中均可使用。谢谢。
Digao

22

如果您在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);

3
我尝试了您的解决方案,它可以在IDE中使用,但是当您制作spring jar时,输入流会有所帮助。
阿美亚


6

在这里查看我的答案:https : //stackoverflow.com/a/56854431/4453282

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

使用这2个导入。

宣布

@Autowired
ResourceLoader resourceLoader;

在某些功能中使用它

Resource resource=resourceLoader.getResource("classpath:preferences.json");

在您的情况下,需要文件时,可以使用以下命令

File file = resource.getFile()

参考:http : //frugalisminds.com/spring/load-file-classpath-spring-boot/ 如先前答案中所述,请勿使用ResourceUtils,它在JAR部署后将无法使用,这也将在IDE中使用部署后


5

在资源中创建json文件夹作为子文件夹,然后在文件夹中添加json文件,然后可以使用以下代码: 在此处输入图片说明

import com.fasterxml.jackson.core.type.TypeReference;

InputStream is = TypeReference.class.getResourceAsStream("/json/fcmgoogletoken.json");

这在Docker中有效。



2

这是我的解决方案。可以帮助某人;

它返回InputStream,但是我想您也可以阅读它。

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jsonschema.json");

1

下面是我的工作代码。

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));

希望对你有帮助!


1

对我来说,该错误有两个修复。

  1. 名为SAMPLE.XML的Xml文件在将以下解决方案部署到AWS EC2时也导致失败。解决方法是将其重命名为new_sample.xml并应用下面给出的解决方案。
  2. 解决方案方法 https://medium.com/@jonathan.henrique.smtp/reading-files-in-resource-path-from-jar-artifact-459ce00d2130

我将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);
      }
  }
}

0

以下一种方法是将资源目录中的类路径中的资源解析为String的最简单方法。

作为字符串(使用Spring库):

         String resource = StreamUtils.copyToString(
                new ClassPathResource("resource.json").getInputStream(), defaultCharset());

此方法使用StreamUtils实用程序,以简洁的紧凑方式将文件作为输入流传输到String中。

如果要将文件作为字节数组,则可以使用基本的Java File I / O库:

作为字节数组(使用Java库):

byte[] resource = Files.readAllBytes(Paths.get("/src/test/resources/resource.json"));

0

我认为问题出在项目所在的文件夹名称中。/home/user/Dev/Java/Java%20Programs/SystemRoutines/target/classes/jsonschema.json

Java程序之间有空格。重命名文件夹名称应使其起作用

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.