hky035
hky035

Reputation: 1

How to use List<String> environment variables in Spring Boot's application.yml?

I am using Spring Boot and trying to declare environment variables in List format in the application.yml file.

Here is the code:

// application.yml
kis:
  domain: ${KIS_DOMAIN:domain}
  appkey:
  - ${KIS_APPKEY_1:appkey}
  - ${KIS_APPKEY_2:appkey}
  appsecret:
  - ${KIS_APPSECRET_1:appsecret}
  - ${KIS_APPSECRET_2:appsecret}
  web-socket-domain: ${KIS_WEBSOCKET_DOMAIN:domain}
// KisProperties.java
@Component
@ConfigurationProperties(prefix = "kis")
@Getter
@Setter
@ToString
public class KisProperties {
    private String domain;
    private String webSocketDomain;
    private List<String> appkey;
    private List<String> appsecret;

   ...
}

When I run this code on Spring Boot version 3.4.0, I get the following error:

Description:

Binding to target [Bindable@651a3e01 type = java.util.List<java.lang.String>, value = 'provided', annotations = array<Annotation>[[empty]], bindMethod = [null]] failed:

    Property: kis.appkey[1]
    Value: "===hidden==="
    Origin: System Environment Property "KIS_APPKEY_1"
    Reason: The elements [kis.appkey[1],kis.appkey[2]] were left unbound.
    Property: kis.appkey[2]
    Value: "===hidden==="
    Origin: System Environment Property "KIS_APPKEY_2"
    Reason: The elements [kis.appkey[1],kis.appkey[2]] were left unbound.

Action:

Update your application's configuration

It outputs that it cannot bind in the List format. I have tried converting it to String[] through the official Spring documentation, or using , as a separator instead of -, but it did not resolve the issue, so I am leaving my question.

Here are my questions:

  1. When using @Value("${kis.appsecret[0]}") private appSecret0, I can run application successfully. Therefore, I think there is no binding method for List types, but I do not understand why.

  2. Why do the error logs increment from index 1, such as kis.appkey[1]?

  3. When I create a new test project (Spring Boot 3.4.3) and use the same structure, it runs successfully. There doesn't seem to be a significant difference according to the official documentation.

  4. How Can I solve it?

Upvotes: 0

Views: 81

Answers (1)

Roar S.
Roar S.

Reputation: 11319

Annotate e.g. your application class (same class that is annotated with @SpringBootApplication) with

@EnableConfigurationProperties(KisProperties.class)

Remove @Component from KisProperties which can be implemented as a record class like this:

@ConfigurationProperties(prefix = "kis")
public record KisProperties(
        String domain,
        String webSocketDomain,
        List<String> appkey,
        List<String> appsecret
) {
}

Verified with Spring Boot 3.4.0 and 3.4.3.

Upvotes: 1

Related Questions