1

I'm trying to load a simple json file from the course path and return via Spring for a testing server I'm putting together.

The file is getting loaded. This is NOT the problem. The problem is getting Spring to send the contents of the file as JSON via the api.

 @RequestMapping(path = "/courses", method = GET)
 public JSONObject getCourses() throws IOException {


Resource resource = resourceLoader.getResource("classpath:samples/course.json");

InputStream resourceInputStream = resource.getInputStream();



if (resourceInputStream == null) {
    throw new NullPointerException("Cannot find resource file " + resource);
}

final JSONTokener tokener = new JSONTokener(resourceInputStream);
return new JSONObject(tokener);

}

But I'm just getting {empty:false} returned from the endpoint.

Any idea how I just send that json?

beek
  • 3,522
  • 8
  • 33
  • 86
  • show your project files tree please – Nick Dec 11 '19 at 04:02
  • Thanks @Nick it's a very big project. These files are in src/main/resources – beek Dec 11 '19 at 04:12
  • try to leave Resource resource = resourceLoader.getResource("samples/course.json"); – Nick Dec 11 '19 at 04:17
  • Can't find the file java.io.FileNotFoundException: Could not open ServletContext resource [/samples/course.json] I think I'm finding the file I'm just trying to get Spring to return it as an object – beek Dec 11 '19 at 04:44
  • @Deadpool this isn't my problem. The file is getting loaded, it's just not being rendered. Please can you remove the duplicate. – beek Dec 11 '19 at 04:45
  • Did you check adding “produces = MediaType.APPLICATION_JSON_VALUE” in the @RequestMapping ? – heyitsvajid Dec 11 '19 at 05:04

2 Answers2

2

As you are using spring web framework why not to use jackson for json processing. you can try this way:

@Autowired
ObjectMapper objectMapper;

@Autowired
ResourceLoader resourceLoader;

@GetMapping("/test")
public JsonNode test() throws IOException {
    JsonNode node = objectMapper.readValue(resourceLoader.getResource("classpath:/samples/course.json").getURL(), JsonNode.class);
    return node;
}

The result of my test:

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = [{"course":"course1"},{"course":"course1"},{"course":"course1"},{"course":"course1"}]
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

EDIT explanation why JSONObject returns {empty:false}

Spring for json processing uses jackson library. this library doesn't know what is java org.json.JSONObject. so it deals with it as simple POJO that can be serialized with common rules/notations. jackson finds method isEmpty() into JSONObject and as naming of this method looks like POJO getter returns its value. if you want jackson to correctly process org.json.* classes you can use special module from:

https://github.com/FasterXML/jackson-datatype-json-org

and register this module with your objectmapper bean:

   @Bean
    Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer( ){
        return jacksonObjectMapperBuilder -> {
            jacksonObjectMapperBuilder.modules(new JsonOrgModule());
        };
    }

after this change your orj.json.* objects should be serialized as expected.

P.S.

jackson can serialize map as json so you can also transform your JSONOBject into map. jsonObject.toMap() and return. this way no extra modules are required.

Nonika
  • 2,490
  • 13
  • 15
0

Did this in the end:

@RequestMapping(path = "/courses", method = GET)
public Object getCourses() throws IOException {

    Resource resource = resourceLoader.getResource("classpath:samples/" + file);

    InputStream resourceInputStream = resource.getInputStream();

    JSONTokener tokener = new JSONTokener(resourceInputStream);
    JSONObject root = new JSONObject(tokener);

    ObjectMapper m = new ObjectMapper();
    Object object = m.readValue(root.toString(), Object.class);
    return object;
}
beek
  • 3,522
  • 8
  • 33
  • 86