【问题标题】:Best way to load some JSON files into a Spring Boot application将一些 JSON 文件加载到 Spring Boot 应用程序中的最佳方法
【发布时间】:2016-03-20 13:05:07
【问题描述】:

我即将创建一个 Rest webservice 应用程序,我需要在应用程序启动时加载作为参数传递的文件夹中存在的所有 JSON 文件(在 application.yml 先验中),以便稍后在方法中使用它们webservices 作为 bean 的列表(每个 JSON 文件对应一个 bean)。

进一步说明我的要求的示例:

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 文件:

    {  
   "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 将包含先验的 JSON 文件信息:

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

还有一个名为 Operator.java 的类,其中包含所有操作员信息。

是否有一种方法可以在应用程序启动时初始化包含所有 JSON 文件信息的 ContextOperatorBean 对象列表,并在我的 Web 服务方法(RestAPI.java 类)中使用它们?

【问题讨论】:

  • "(...) 稍后在 web 服务的方法中将它们用作 bean 列表(每个 json 文件对应一个 bean)" - 你能解释一下吗更详细,最好显示一个例子。

标签: java json spring-boot


【解决方案1】:

不知道以下简单实现是否满足“最佳”标准,但您可以创建一个新服务来处理此责任,例如:

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

注意:省略了处理失败或意外情况以及一些实现细节。

然后在你的控制器中@Autowire它并调用getMatchingOperators()来过滤匹配的条目。

【讨论】:

  • 对我来说,这个实现满足“最好”的标准。非常感谢克里格。效果很好
  • 嗨@Kryger,感谢您的解决方案,我有类似的问题集,但String jsonConfigFolder; 始终指向null。我可能做错了什么?
  • 这可能是因为你的组件没有被 Spring 拾取,很可能没有包含在组件扫描中或通过 new 实例化。如果这没有帮助,您最好的选择是发布一个新问题并详细描述您的问题。
  • 唯一的改变,我会使用 InputStream 而不是文件对象,所以我可以很容易地从类路径中读取
猜你喜欢
  • 2020-06-19
  • 2022-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-09
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 2020-02-14
相关资源
最近更新 更多