23

I'm about to create a Rest webservice application, and I need to load all JSON files that exist in a folder passed as parameter (in application.yml a priori), on application startup, to use them later in the methods of webservices as a list of beans (every JSON file corresponds to a bean).

A sample to further explain my requirements:

application.yml:

json.config.folder: /opt/my_application/json_configs

MyApplication.java:

package com.company;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

JSON Files having this structure:

    {  
   "key":"YYYYY",
   "operator_list":[  
        {  
           "name":"operator1",
           "configs":{  
               "id":"XXXXX1",
               "path":"xxxx2"
           }
        },
        {  
            "name":"operator2",
            "configs":{  
                "id":"XXXXX1",
                "passphrase":"xxxx2",
                "user_id":"XXXX3",
                "password":"XXXXX"
            }
        },
        {  
            "name":"operator3",
            "configs":{  
                "user_id":"XXXXX1"
            }
        }
    ]
    }

RestAPI.java

@RestController
@RequestMapping("/my_app_url")
@PropertySource(value={"classpath:application.yml"})
public class RestAPI {
    //Some fields
    ....

    //Some methods
    ....

    //Method that return operator list of a given context (correspond to the field "key" of the json file)
    @RequestMapping("/getOperatorList")
    public List<Operator> getOperatorList(@RequestParam(value = "context", defaultValue = "YYYYY") String context) throws Exception{
        List<Operator> result = null;
        //Here, i need to loop the objects , that are supposed to be initialized during application startup 
        //(but i I do not know yet how to do it) with data from JSON files
        //to find the one that correspond to the context in parameter and return its operator list

        return result;
    }
}

ContextOperatorBean.java that will contain JSON file infos a priori:

package com.company.models;

import java.util.List;

public class ContextOperatorBean {
    String key;
    List<Operator> operator_list;

    public ContextOperatorBean() {
    }

    public ContextOperatorBean(String key, List<PaymentMethod> operator_list) {
        this.key = key;
        this.operator_list = operator_list;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public List<Operator> getOperator_list() {
        return operator_list;
    }

    public void setOperator_list(List<Operator> operator_list) {
        this.operator_list = operator_list;
    }
}

And another class called Operator.java containing all operator infos.

Is there a method to initialize a ContextOperatorBean object list that contain infos of all JSON files, on application startup, and use them in my webservice methods (RestAPI.java class)?

kryger
  • 12,906
  • 8
  • 44
  • 65
diamah
  • 333
  • 1
  • 2
  • 7
  • 1
    _"(...) to use them later in the methods of webservices as a list of beans (every json file corresponds to a bean)"_ - could you explain this in more detail, preferably showing an example. – kryger Dec 14 '15 at 22:49

1 Answers1

16

No idea if the following naïve implementation satisfies the criterium of being "best", but you could create a new service that deals with this responsibility, for example:

@Service
public class OperatorsService {

    @Value("${json.config.folder}")
    String jsonConfigFolder;

    List<ContextOperatorBean> operators = new ArrayList<>();

    @PostConstruct
    public void init() throws IOException {
        ObjectMapper jsonMapper = new ObjectMapper();
        for (File jsonFile : getFilesInFolder(jsonConfigFolder)) {
            // deserialize contents of each file into an object of type
            ContextOperatorBean operator = jsonMapper.readValue(jsonFile, new TypeReference<List<ContextOperatorBean>>() {});
            operators.add(operator);
        }
    }

    public List<ContextOperatorBean> getMatchingOperators(String context) {
        return operators.stream().filter(operator -> checkIfMatches(operator, context)).collect(Collectors.toList());
    }

    private boolean checkIfMatches(ContextOperatorBean operator, String context) {
        // TODO implement
        return false;
    }

    private File[] getFilesInFolder(String path) {
        // TODO implement
        return null;
    }
}

NOTE: left out handling failures or unexpected conditions and some implementation details.

Then @Autowire it in your controller and call getMatchingOperators() to filter only matching entries.

kryger
  • 12,906
  • 8
  • 44
  • 65
  • For me, this implementation satisfies the criterium of being "best". Thank you very much Kryger. it works very well – diamah Dec 15 '15 at 16:43
  • Hi @Kryger, Thanks for the solution, i have a similar problem set, but the `String jsonConfigFolder;` is always pointing to `null`. What could i be doing wrong? – Napster Aug 05 '16 at 14:06
  • This could be explained by your component not being picked up by Spring, most likely not included in component scanning or instantiated via `new`. If this doesn't help your best option would be to post a new question and describe your problem in detail. – kryger Aug 08 '16 at 08:15
  • the only change, I would use InputStream instead of file object, so I can read easily from classpath – Kalpesh Soni Sep 12 '18 at 20:40