user9347049
user9347049

Reputation: 2055

How to parse JSON placed in resource folder in SpringBoot

Hi I am trying to parse a JSON that I have saved in a resource folder and test it. So I took these steps for now.

DataLoader.java

@Service
public class DataLoader {

private static ObjectMapper  objectMapper = defaultObjectMapper();

  private static ObjectMapper defaultObjectMapper(){
    ObjectMapper  defaultObjectMapper = new ObjectMapper();
    //defaultObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    return defaultObjectMapper;
  }

  public static JsonNode parse(String str) throws IOException {
    return objectMapper.readTree(str);
  }

  public static <A> A fromJason(JsonNode node, Class<A> clazz) throws JsonProcessingException {
    return objectMapper.treeToValue(node, clazz);
  }

}

DataLoaderTest.java

public class DataLoaderTest {

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

    //private String jsonSource = "{\"title\":\"new book\"}";

    @Test
    public void parse() throws IOException {
        JsonNode node = DataLoader.parse(jsonSource);
        assertEquals(node.get("title").asText(), "new book");
    }

    @Test
    public void fromJson() throws IOException {
        JsonNode node = DataLoader.parse(jsonSource);
        Fruit pojo = DataLoader.fromJason(node, Fruit.class);
        System.out.println("Pojo title " + pojo.title);
    }

}

So when I test it with //private String jsonSource = "{\"title\":\"new book\"}"; everything is working fine.

When I try to load JSON file from resources folder I am getting error:

error: incompatible types: Resource cannot be converted to String JsonNode node = ApxDataLoader.parse(jsonSource);

Any help highly appreciated.

Upvotes: 5

Views: 15243

Answers (2)

jmbourdaret
jmbourdaret

Reputation: 261

with Spring-boot, the easy way to load a json in the classpath (for example in the resources folder) would be :

File jsonFile = new ClassPathResource("data.json").getFile();
// or
File jsonFile = jsonResource.getFile();

JsonNode node = objectMapper.readTree(jsonFile);

No need to deal with InputStream, Spring takes care of that for you. and Jackson can read a File directly, so no need for a String neither.

No need to deal with JsonNode neither: You can also even further optimize the readability of the code by doing all the parsing/mapping at the same time :

Fruit myFruit = objectMapper.readValue(jsonFile, Fruit.class);

If you still need the contents of the file as a String for some reason:

String jsonString = Files.readString(jsonFile.toPath()); // default charset of readString is UTF8 

DataLoader could have only one method:

public class DataLoader {

  // ... objectmapper stuff ...

  public static <A> A fromJason(Resource jsonResource, Class<A> clazz) throws JsonProcessingException {
    return objectMapper.readValue(jsonResource.getFile(), clazz);
  }

Upvotes: 8

Yogesh_D
Yogesh_D

Reputation: 18809

The Resource object is not a string. To parse it to the appropriate JSON structure, you would have to read the Resource. See: https://www.baeldung.com/spring-load-resource-as-string

Here's: The relevant part copied from the article.

public static String asString(Resource resource) {
        try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) {
            return FileCopyUtils.copyToString(reader);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

Which should give you the string read from the Resource.

Another option you have is to use the InputStream from the resource and pass it to the overloaded readTree() method that can take an input stream.

See : https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html#readTree(java.io.InputStream)

I would recommend the second approach instead of reading the whole file as a String and then passing it to the ObjectMapper.

Upvotes: 1

Related Questions