启动应用程序时从 json 加载值

问题描述 投票:0回答:1

我想在 Spring Boot 应用程序启动时从 json 文件加载值。

我的配置文件代码如下:

@Configuration
@Getter
public class FedexAPIConfig {

    private final static String JSON_FILE = "/static/config/fedex-api-credentials.json";
    private final boolean IS_PRODUCTION = false;
    private FedexAPICred apiCredentials;

    public FedexAPIConfig() {
        try (InputStream in = getClass().getResourceAsStream(JSON_FILE);
                BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
            JSONObject json = new JSONObject();

            // this.apiCredentials = new JSONObject(new JSONTokener(reader));
            
            if (IS_PRODUCTION) {
                json = new JSONObject(new JSONTokener(reader)).getJSONObject("production");
            } else {
                json = new JSONObject(new JSONTokener(reader)).getJSONObject("test");
            }
            System.out.println(json.toString());
            this.apiCredentials = FedexAPICred.builder()
                    .url(json.optString("url"))
                    .apiKey(json.optString("api_key"))
                    .secretKey(json.optString("secret_key"))
                    .build();
        } catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这样,当应用程序启动时,值就会成功打印在控制台上。Startup console log

当我尝试从其他普通类调用这个值时,如下所示:,它什么也没带来,只是抛出 NullPointerException...我的错误是什么,我该怎么办?

public class FedexOAuthTokenManager extends OAuthToken {
    private static final String VALIDATE_TOKEN_URL = "/oauth/token";
    private static final String GRANT_TYPE_CLIENT = "client_credentials";
    private static final String GRANT_TYPE_CSP = "csp_credentials";

    @Autowired
    private FedexAPIConfig fedexApiConfig;

    @Autowired
    private Token token;

    @Override
    public void validateToken() {
        // This is the part where "fedexApiConfig" is null.
        FedexAPICred fedexApiCred = fedexApiConfig.getApiCredentials();
        Response response = null;
        try {
            RequestBody body = new FormBody.Builder()
                    .add("grant_type", GRANT_TYPE_CLIENT)
                    .add("client_id", fedexApiCred.getApiKey())
                    .add("client_secret", fedexApiCred.getSecretKey())
                    .build();

            response = new HttpClient().post(fedexApiCred.getUrl() + VALIDATE_TOKEN_URL, body);
            
            if (response.code() == 200) {
                JSONObject json = new JSONObject(response.body().string());

                token.setAccessToken(json.optString("access_token"));
                token.setTokenType(json.optString("token_type"));
                token.setExpiredIn(json.optInt("expires_in"));
                token.setExpiredDateTime(LocalDateTime.now().plusSeconds(json.optInt("expires_in")));
                token.setScope(json.optString("scope"));

            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

fedexApiConfg 为空,即使我在调用之前自动连接它。 这个 FedexOAuthTokenManager 是通过 new FedexOAuthTokenManager() 从其他 @Component 类调用的

spring-boot configuration
1个回答
-1
投票

你有像下面这样尝试过吗?

第 1 步:创建一个如下所示的配置类

public class DemoConfig implements ApplicationListener<ApplicationPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent event) {
        
        //Load the values from the JSON file and populate the application 
        //properties dynamically 
        ConfigurableEnvironment environment = event.getApplicationContext().getEnvironment();
        Properties props = new Properties();
        props.put("spring.datasource.url", "<my value>");
        //Add more properties
        environment.getPropertySources().addFirst(new PropertiesPropertySource("myProps", props));

    }

要监听上下文事件,bean 应该实现 ApplicationListener 接口,该接口只有一个方法 onApplicationEvent()。ApplicationPreparedEvent 在应用程序生命周期的早期被调用

第2步:在src/main/resources/META-INF/spring.factories中自定义

org.springframework.context.ApplicationListener=com.example.demo.DemoConfig

第3步:Spring Boot中的@Value通常用于将配置值注入到Spring Boot应用程序中。根据您的意愿访问属性。

    @Value("${spring.datasource.url}")
    private String valueFromJSon;

首先在本地计算机中尝试此示例,然后相应地修改您的更改。

参考 - https://www.baeldung.com/spring-value-annotation

© www.soinside.com 2019 - 2024. All rights reserved.