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

c6ubokkw  于 2022-09-18  发布在  Spring
关注(0)|答案(15)|浏览(294)

我使用的是Spring Boot和json-schema-validator。我正在尝试从resources文件夹中读取名为jsonschema.json的文件。我试了几种不同的方法,但都不能奏效。这是我的密码。

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)

我在代码中做错了什么?

ejk8hzay

ejk8hzay1#

在花了很多时间试图解决这个问题后,终于找到了一个可行的解决方案。该解决方案利用了Spring的ResourceUtils。应该也适用于json文件。

感谢Lokesh Gupta撰写的精彩页面:Blog

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

回答人们对这些评论的一些担忧:

我非常确定我使用java -jar target/image-service-slave-1.0-SNAPSHOT.jar在Amazon EC2上运行了这个程序

查看我的GitHub repo:https://github.com/johnsanthosh/image-service,找出从JAR运行它的正确方式。

abithluo

abithluo2#

非常简短的回答:您要在类加载器的类的作用域中查找资源,而不是在目标类中。这应该是可行的:

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

此外,这可能是有帮助的读物:

另外,有这样一种情况:一个项目在一台机器上编译,然后在另一台机器上启动,或者在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");
rslzwgfq

rslzwgfq3#

例如,如果您在Resources文件夹下有配置文件夹,我尝试了这个类,希望对您有帮助

File file = ResourceUtils.getFile("classpath:config/sample.txt")

//Read File Content
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);
k75qkfdt

k75qkfdt4#

花了太多时间回到这一页,所以就把这个留在这里:

File file = new ClassPathResource("data/data.json").getFile();
pqwbnv8z

pqwbnv8z5#

2021最好的方式

读取文件的最简单方法是:

Resource resource = new ClassPathResource("jsonSchema.json");
    FileInputStream file = new FileInputStream(resource.getFile());
t5zmwmid

t5zmwmid6#

点击此处查看我的答案:https://stackoverflow.com/a/56854431/4453282

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

使用这两个导入。

申报

@Autowired
ResourceLoader resourceLoader;

在某些函数中使用它

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

在您的情况下,因为您需要文件,所以可以使用以下文件

File file = resource.getFile()

参考:http://frugalisminds.com/spring/load-file-classpath-spring-boot/在前面的回答中已经提到,不要使用资源实用程序它在JAR部署后不工作,这将在IDE中工作,也可以在部署后工作

up9lanfz

up9lanfz7#

以下是我的工作代码。

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

希望这对一个人有帮助!

t9aqgxwy

t9aqgxwy8#

如何可靠获取资源

要可靠地从Spring Boot应用程序的资源中获取文件,请执行以下操作:

1.找到传递抽象资源的方法,例如InputStreamURL而不是File
1.使用框架工具获取资源

示例:从resources读取文件

public class SpringBootResourcesApplication {
    public static void main(String[] args) throws Exception {
        ClassPathResource resource = new ClassPathResource("/hello", SpringBootResourcesApplication.class);
        try (InputStream inputStream = resource.getInputStream()) {
            String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
            System.out.println(string);
        }
    }
}
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    └── main
        ├── java
        │   └── com
        │       └── caco3
        │           └── springbootresources
        │               └── SpringBootResourcesApplication.java
        └── resources
            ├── application.properties
            └── hello

上面的示例可以在IDE和JAR中使用

更深层次解释

优先选择抽象资源,而不是File

  • 抽象资源的示例为InputStreamURL

  • 避免使用File,因为并不总是可以从类路径资源中获取它

  • 例如,以下代码可以在IDE中运行:

public class SpringBootResourcesApplication {
    public static void main(String[] args) throws Exception {
        ClassLoader classLoader = SpringBootResourcesApplication.class.getClassLoader();
        File file = new File(classLoader.getResource("hello").getFile());

        Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)
                .forEach(System.out::println);
    }
}

,但在运行Spring Boot JAR时失败,错误为:

java.nio.file.NoSuchFileException: file:/home/caco3/IdeaProjects/spring-boot-resources/target/spring-boot-resources-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/hello
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
  • 如果您使用外部库,并且它要求您提供资源,请尝试找到一种方法将InputStreamURL传递给它

  • 例如,问题中的JsonLoader.fromFile可以替换为JsonLoader.fromURL方法:它接受URL

使用框架的功能获取资源:

Spring框架支持通过ClassPathResource访问类路径资源

您可以使用它:

1.直接,如从resources读取文件的示例

  • 间接:

1.使用@Value

@SpringBootApplication
public class SpringBootResourcesApplication implements ApplicationRunner {
    @Value("classpath:/hello") // Do not use field injection
    private Resource resource;

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootResourcesApplication.class, args);
    }

   @Override
   public void run(ApplicationArguments args) throws Exception {
       try (InputStream inputStream = resource.getInputStream()) {
           String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
           System.out.println(string);
       }
   }
}
@SpringBootApplication
public class SpringBootResourcesApplication implements ApplicationRunner {
    @Autowired // do not use field injection
    private ResourceLoader resourceLoader;

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringBootResourcesApplication.class, args);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Resource resource = resourceLoader.getResource("/hello");
        try (InputStream inputStream = resource.getInputStream()) {
            String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
            System.out.println(string);
        }
    }
}
9jyewag0

9jyewag09#

在资源中创建json文件夹作为子文件夹,然后在文件夹中添加json文件,然后可以使用代码:

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

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

这在Docker中有效。

niknxzdl

niknxzdl10#

以下是我的解决方案。可能会帮助某些人;

它返回InputStream,但我假设您也可以从中读取。

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

nsc4cvqm11#

陷入同样的问题,这对我有帮助

URL resource = getClass().getClassLoader().getResource("jsonschema.json");
JsonNode jsonNode = JsonLoader.fromURL(resource);
afdcj2ne

afdcj2ne12#

将RESOURCES目录中的类路径中的资源解析为字符串的最简单方法是以下一行。

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

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

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

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

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

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

sqyvllje13#

如果您使用的是springjackson(大多数较大的应用程序都会使用),则使用简单的内联:

JsonNode json = new ObjectMapper().readTree(new ClassPathResource("filename").getFile());

7vux5j2d

7vux5j2d14#

Spring提供了可用于加载文件的ResourceLoader

@Autowired
ResourceLoader resourceLoader;

// path could be anything under resources directory
File loadDirectory(String path){
        Resource resource = resourceLoader.getResource("classpath:"+path); 
        try {
            return resource.getFile();
        } catch (IOException e) {
            log.warn("Issue with loading path {} as file", path);
        }
        return null;
 }

已参考此link

eivnm1vs

eivnm1vs15#

对我来说,这个错误有两个修复方法。

1.名为SAMPLE.XML的XML文件,该文件在部署到AWS EC2时甚至会导致以下解决方案失败。修复方法是将其重命名为new_sample.xml并应用下面给出的解决方案。
1.解决方案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);
      }
  }
}

相关问题