如何从 Spring Boot 中的资源中读取 JSON 文件

Posted

技术标签:

【中文标题】如何从 Spring Boot 中的资源中读取 JSON 文件【英文标题】:How to read JSON file from resources in Spring Boot 【发布时间】:2020-03-01 09:12:41 【问题描述】:

使用 Spring Boot 2.1.5 Release,创建了以下示例 Spring Boot 微服务:

Maven 项目结构:

MicroService
    │
    pom.xml
    src
    │
    └───main
        │ 
        ├───java
        │   │ 
        │   └───com
        │       └───microservice
        │           │
        │           └───MicroServiceApplication.java  
        │  
        └───resources
            │
            └───data.json
                │                    
                application.properties

有以下 JSON 文件(在 src/main/resources/data.json 中):

"firstName": "John", "lastName": "Doe"

微服务应用:

@SpringBootApplication
public class MicroServiceApplication 

    @Bean
    CommandLineRunner runner() 
        return args -> 
            String data = FilePathUtils.readFileToString("../src/main/resources/data.json", MicroServiceApplication.class);
            System.out.println(data);
        ;
    

    public static void main(String[] args) 
        SpringApplication.run(MicroServiceApplication.class, args);
    

抛出以下异常:

  java.lang.IllegalStateException: Failed to execute CommandLineRunner
  ...
  Caused by: java.io.IOException: Stream is null

FilePathUtils.java:

import io.micrometer.core.instrument.util.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

public class FilePathUtils 
    public static String readFileToString(String path, Class aClazz) throws IOException 

        try (InputStream stream = aClazz.getClassLoader().getResourceAsStream(path)) 
            if (stream == null) 
                throw new IOException("Stream is null");
            
            return IOUtils.toString(stream, Charset.defaultCharset());
        
    

我可能做错了什么?

【问题讨论】:

【参考方案1】:

虽然@Deadpool 已经提供了答案,但我想补充一点,当spring boot 的神器创建时,已经没有src/main/ 文件夹了(您可以打开spring boot 神器并自行确定)。

所以你不能像这样加载资源:

FilePathUtils.readFileToString("../src/main/resources/data.json", MicroServiceApplication.class);

Spring 确实有一个名为 Resource 的抽象,可以在应用程序中使用,甚至可以注入到类/配置中:

@Value("classpath:data/data.json")
Resource resourceFile;

注意前缀“classpath”,它意味着资源将从类路径中解析(读取正确打包到工件中的所有内容)。

有一个很不错的Tutorial,可以很方便

【讨论】:

谢谢,我喜欢@Value("classpath:data/data.json") 注释。 :) 什么是Resourcejavax.faces.application.Resource? @e-info128 docs.spring.io/spring-framework/docs/current/javadoc-api/org/…【参考方案2】:

在spring boot项目中可以使用ResourceUtils

Path file = ResourceUtils.getFile("data/data.json").toPath();

ClassPathResource

String clsPath =  new ClassPathResource("data/data.json").getPath();

有时如果您正在阅读不同的扩展文件,例如.graphql.mmdb.json,您需要使用spring ResourceLoader 将其读取为InputStream,这个article 有明确的解释

@Autowire
private ResourceLoader resourceLoader;

   Resource resource =resourceLoader.getResource("classpath:GeoLite2-Country.mmdb");
   InputStream dbAsStream = resource.getInputStream();

并使用Files.copyInputStream复制到临时文件

Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);

【讨论】:

【参考方案3】:

您可以使用jakson-databind

Jackson ObjectMapper 类 (com.fasterxml.jackson.databind.ObjectMapper) 是解析 JSON 的最简单方法之一。 Jackson ObjectMapper can parse JSON 来自字符串、流或文件,create a Java object or object graph 表示已解析的 JSON。 Parsing JSON 转换为 Java 对象也称为 deserialize Java objects 从 JSON。

// create Object Mapper
ObjectMapper mapper = new ObjectMapper();

// read JSON file and map/convert to java POJO
try 
    SomeClass someClassObject = mapper.readValue(new File("../src/main/resources/data.json"), SomeClass.class);
    System.out.println(someClassObject);
 catch (IOException e) 
    e.printStackTrace();

你应该在你的.pom文件中有jakson-databind

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.4</version>
</dependency>

【讨论】:

以上是关于如何从 Spring Boot 中的资源中读取 JSON 文件的主要内容,如果未能解决你的问题,请参考以下文章

spring boot框架学习之重要注解3注解方式读取外部资源配置文件

使用@sql spring boot test从资源文件夹以外的自定义位置读取.sql文件

Spring Boot参考教程Spring Boot Jar方式读取资源文件

无法从 Spring Boot 中的外部属性文件中读取值

Spring Boot Jar 包启动时如何加载外部资源

Spring Boot Jar 包启动时如何加载外部资源