从Spring Boot中的resources文件夹中读取文件

时间:2017-06-06 20:38:42

标签: java spring spring-boot json-schema-validator

我使用的是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);

这是文件的位置。

enter image description here

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

enter image description here

但是当我运行代码时,我收到以下错误。

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

我在代码中做错了什么?

18 个答案:

答案 0 :(得分:49)

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

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

enter image description here

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

答案 1 :(得分:16)

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

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

另外,请看:

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

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

答案 2 :(得分:7)

如果您在“资源”文件夹下有例如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 :(得分:4)

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

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

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

这适用于Docker。

答案 4 :(得分:4)

花了太多时间返回此页面,所以就把它留在这里:

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

答案 5 :(得分:2)

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

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

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

答案 6 :(得分:1)

坚持同样的问题,这有助于我

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

答案 7 :(得分:1)

以下既可在 IDE 中运行,又可在终端中将其作为 jar 运行,

import org.springframework.core.io.Resource;

@Value("classpath:jsonschema.json")
Resource schemaFile;
    
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4);
JsonSchema jsonSchema = factory.getSchema(schemaFile.getInputStream());

答案 8 :(得分:1)

如果你在你的项目中使用maven资源过滤器,你需要配置在pom.xml中加载什么样的文件。如果不这样做,无论您选择哪个类来加载资源,都不会被找到。

pom.xml

<resources>
    <resource>
        <directory>${project.basedir}/src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.yml</include>
            <include>**/*.yaml</include>
            <include>**/*.json</include>
        </includes>
    </resource>
</resources>

答案 9 :(得分:1)

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

答案 10 :(得分:1)

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

    名为SAMPLE.XML的
  1. 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);
      }
  }
}

答案 11 :(得分: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));

希望有帮助!

答案 12 :(得分:0)

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

作为字符串(使用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"));

答案 13 :(得分:0)

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

Java程序之间有空格。重命名文件夹名称应该可以使其工作

答案 14 :(得分:0)

如果您使用 springjackson(大多数大型应用程序都会使用),请使用简单的单行:

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

答案 15 :(得分:0)

在这里查看我的答案: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/ 正如前面的答案中已经提到的,不要使用ResourceUtils,它在JAR部署后不起作用,这将在IDE中以及部署后都起作用

答案 16 :(得分:0)

我遇到了同样的问题,因为我只需要获取要发送到文件输入流的文件路径,我就这样做了。

   return componet && (
      <TemplateMarker
        // backgroundColor="#327ba8"
        width={element.w}
        height={element.h}
        x={element.x}
        y={element.y}
        key={element.id}
        skewX={element.skewX ?? template.skewX}
        skewY={element.skewY ?? template.skewY}
        labelComponent={componet}
        onClick={handleClick}
      />
    );

答案 17 :(得分:0)

使用 Spring ResourceUtils.getFile() 你不必注意绝对路径 :)

 private String readDictionaryAsJson(String filename) throws IOException {
    String fileContent;
    try {
        File file = ResourceUtils.getFile("classpath:" + filename);
        Path path = file.toPath();
        Stream<String> lines = Files.lines(path);
        fileContent = lines.collect(Collectors.joining("\n"));
    } catch (IOException ex) {
        throw ex;
    }
    return new fileContent;
}