Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read JSON file from resources in Spring Boot

Using Spring Boot 2.1.5 Release, have created the following sample Spring Boot Microservice:

Maven Project Structure:

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

Have the following JSON file (inside src/main/resources/data.json):

{"firstName": "John", "lastName": "Doe"}

MicroServiceApplication:

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

Throws the following exception:

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

What am I possibly being doing wrong?

like image 707
PacificNW_Lover Avatar asked Nov 05 '19 02:11

PacificNW_Lover


3 Answers

You can use the jackson-databind library.

The Jackson ObjectMapper class (com.fasterxml.jackson.databind.ObjectMapper) is one of the simplest way to parse JSON. The Jackson ObjectMapper can parse JSON from a string, stream or file, and create a Java object or object graph representing the parsed JSON. Parsing JSON into Java objects is also referred to as to deserialize Java objects from 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();
}

and you shoud have jackson-databind in your .pom file :

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.4</version>
</dependency>
like image 195
Yaakoubox Youcef Hedjerci Avatar answered Oct 27 '22 02:10

Yaakoubox Youcef Hedjerci


In spring boot project you can use ResourceUtils

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

or ClassPathResource

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

Sometimes if you are reading different extension file like .graphql or .mmdb or .json you need to read it as InputStream using spring ResourceLoader, this article has clear explanation

@Autowire
private ResourceLoader resourceLoader;

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

And copy the InputStream to temp file using Files.copy

Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
like image 39
Deadpool Avatar answered Oct 27 '22 00:10

Deadpool


While @Deadpool has provided the answer, I would like to add that when the artifact of spring boot is created there is no such src/main/ folder anymore (you can open the spring boot artifact and make sure by yourself).

So you can't load resources like this:

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

Spring indeed has an abstraction called Resource that can be used in the application, that can even be injected into the classes / configuration:

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

Notice the prefix "classpath" it means that the resource will be resolved from the classpath (read everything properly packaged into the artifact).

There is a pretty good Tutorial that can be handy

like image 33
Mark Bramnik Avatar answered Oct 27 '22 02:10

Mark Bramnik