如何从 Spring 引导中的资源读取 JSON 文件
How to read JSON file from resources in Spring Boot
使用 Spring Boot 2.1.5 版本,创建了以下示例 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());
}
}
}
我可能做错了什么?
在spring引导项目中你可以使用ResourceUtils
Path file = ResourceUtils.getFile("data/data.json").toPath();
或ClassPathResource
String clsPath = new ClassPathResource("data/data.json").getPath();
有时,如果您正在读取不同的扩展文件,例如 .graphql
或 .mmdb
或 .json
,您需要使用 spring ResourceLoader
,这个article有明确的解释
@Autowire
private ResourceLoader resourceLoader;
Resource resource =resourceLoader.getResource("classpath:GeoLite2-Country.mmdb");
InputStream dbAsStream = resource.getInputStream();
并使用 Files.copy
将 InputStream
复制到临时文件
Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
虽然@Deadpool 已经提供了答案,但我想补充一点,当创建 spring 引导的工件时,不再有这样的 src/main/
文件夹(您可以打开 spring开机神器自己确定)。
所以你不能像这样加载资源:
FilePathUtils.readFileToString("../src/main/resources/data.json", MicroServiceApplication.class);
Spring 确实有一个名为 Resource
的抽象,可以在应用程序中使用,甚至可以注入到 类 / 配置中:
@Value("classpath:data/data.json")
Resource resourceFile;
注意前缀 "classpath",这意味着资源将从类路径中解析(读取正确打包到工件中的所有内容)。
有个不错的Tutorial可以用得上
您可以使用 jackson-databind
库。
Jackson ObjectMapper
class (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
文件中应该有 jackson-databind
:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>
使用 Spring Boot 2.1.5 版本,创建了以下示例 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());
}
}
}
我可能做错了什么?
在spring引导项目中你可以使用ResourceUtils
Path file = ResourceUtils.getFile("data/data.json").toPath();
或ClassPathResource
String clsPath = new ClassPathResource("data/data.json").getPath();
有时,如果您正在读取不同的扩展文件,例如 .graphql
或 .mmdb
或 .json
,您需要使用 spring ResourceLoader
,这个article有明确的解释
@Autowire
private ResourceLoader resourceLoader;
Resource resource =resourceLoader.getResource("classpath:GeoLite2-Country.mmdb");
InputStream dbAsStream = resource.getInputStream();
并使用 Files.copy
InputStream
复制到临时文件
Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
虽然@Deadpool 已经提供了答案,但我想补充一点,当创建 spring 引导的工件时,不再有这样的 src/main/
文件夹(您可以打开 spring开机神器自己确定)。
所以你不能像这样加载资源:
FilePathUtils.readFileToString("../src/main/resources/data.json", MicroServiceApplication.class);
Spring 确实有一个名为 Resource
的抽象,可以在应用程序中使用,甚至可以注入到 类 / 配置中:
@Value("classpath:data/data.json")
Resource resourceFile;
注意前缀 "classpath",这意味着资源将从类路径中解析(读取正确打包到工件中的所有内容)。
有个不错的Tutorial可以用得上
您可以使用 jackson-databind
库。
Jackson ObjectMapper
class (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
文件中应该有 jackson-databind
:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>