I have a Spring Boot 3.2 application with :
An environment variable
<code>SPRING_APPLICATION_JSON={"basic-auth":{"users":[{"name":"user1","password":"pw1","role":"R1"},{"name":"user2","password":"pw2","role":"R2"}],"patterns":[{"matchers":"/m1/**","role":"R1"},{"matchers":"/m2/**","role":"R2"}]}}
</code>
<code>SPRING_APPLICATION_JSON={"basic-auth":{"users":[{"name":"user1","password":"pw1","role":"R1"},{"name":"user2","password":"pw2","role":"R2"}],"patterns":[{"matchers":"/m1/**","role":"R1"},{"matchers":"/m2/**","role":"R2"}]}}
</code>
SPRING_APPLICATION_JSON={"basic-auth":{"users":[{"name":"user1","password":"pw1","role":"R1"},{"name":"user2","password":"pw2","role":"R2"}],"patterns":[{"matchers":"/m1/**","role":"R1"},{"matchers":"/m2/**","role":"R2"}]}}
An application.yml containing
<code>application:
basic-auth:
users:
- name: ${basic-auth.users[0].name}
password: ${basic-auth.users[0].password}
role: ${basic-auth.users[0].role}
- name: ${basic-auth.users[1].name}
password: ${basic-auth.users[1].password}
role: ${basic-auth.users[1].role}
</code>
<code>application:
basic-auth:
users:
- name: ${basic-auth.users[0].name}
password: ${basic-auth.users[0].password}
role: ${basic-auth.users[0].role}
- name: ${basic-auth.users[1].name}
password: ${basic-auth.users[1].password}
role: ${basic-auth.users[1].role}
</code>
application:
basic-auth:
users:
- name: ${basic-auth.users[0].name}
password: ${basic-auth.users[0].password}
role: ${basic-auth.users[0].role}
- name: ${basic-auth.users[1].name}
password: ${basic-auth.users[1].password}
role: ${basic-auth.users[1].role}
A class for the properties
<code> @Component
@ConfigurationPropertiesScan
@ConfigurationProperties(prefix = "application")
@Data
public class ApplicationProperties {
private BasicAuth basicAuth;
@Data
public static class BasicAuth {
private List<User> users;
}
@Data
public static class User {
private String name;
private String password;
private String role;
}
}
</code>
<code> @Component
@ConfigurationPropertiesScan
@ConfigurationProperties(prefix = "application")
@Data
public class ApplicationProperties {
private BasicAuth basicAuth;
@Data
public static class BasicAuth {
private List<User> users;
}
@Data
public static class User {
private String name;
private String password;
private String role;
}
}
</code>
@Component
@ConfigurationPropertiesScan
@ConfigurationProperties(prefix = "application")
@Data
public class ApplicationProperties {
private BasicAuth basicAuth;
@Data
public static class BasicAuth {
private List<User> users;
}
@Data
public static class User {
private String name;
private String password;
private String role;
}
}
And an associated service
<code> @Service
public class ApplicationPropertiesService {
private final ApplicationProperties applicationProperties;
public ApplicationPropertiesService(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
public ApplicationProperties.BasicAuth getBasicAuth() {
return applicationProperties.getBasicAuth();
}
}
</code>
<code> @Service
public class ApplicationPropertiesService {
private final ApplicationProperties applicationProperties;
public ApplicationPropertiesService(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
public ApplicationProperties.BasicAuth getBasicAuth() {
return applicationProperties.getBasicAuth();
}
}
</code>
@Service
public class ApplicationPropertiesService {
private final ApplicationProperties applicationProperties;
public ApplicationPropertiesService(ApplicationProperties applicationProperties) {
this.applicationProperties = applicationProperties;
}
public ApplicationProperties.BasicAuth getBasicAuth() {
return applicationProperties.getBasicAuth();
}
}
The controller
<code>@RestController
public class ApplicationController {
private final ApplicationPropertiesService applicationPropertiesService;
public ApplicationController(ApplicationPropertiesService applicationPropertiesService) {
this.applicationPropertiesService = applicationPropertiesService;
}
@GetMapping(path = "/basic")
public void basic() {
System.out.println("hello");
System.out.println(applicationPropertiesService.getBasicAuth().getUsers().get(0).getName());
}
}
</code>
<code>@RestController
public class ApplicationController {
private final ApplicationPropertiesService applicationPropertiesService;
public ApplicationController(ApplicationPropertiesService applicationPropertiesService) {
this.applicationPropertiesService = applicationPropertiesService;
}
@GetMapping(path = "/basic")
public void basic() {
System.out.println("hello");
System.out.println(applicationPropertiesService.getBasicAuth().getUsers().get(0).getName());
}
}
</code>
@RestController
public class ApplicationController {
private final ApplicationPropertiesService applicationPropertiesService;
public ApplicationController(ApplicationPropertiesService applicationPropertiesService) {
this.applicationPropertiesService = applicationPropertiesService;
}
@GetMapping(path = "/basic")
public void basic() {
System.out.println("hello");
System.out.println(applicationPropertiesService.getBasicAuth().getUsers().get(0).getName());
}
}
It is working fine.
Now I want to simplify a bit with an application.yml like
<code>application:
basic-auth:
users: ${basic-auth.users}
</code>
<code>application:
basic-auth:
users: ${basic-auth.users}
</code>
application:
basic-auth:
users: ${basic-auth.users}
But is it not working. The application even won’t start.
<code>Failed to bind properties under 'application.basic-auth.users' to java.util.List<com.tuto.properties.ApplicationProperties$User>:
Property: application.basic-auth.users
Value: "${basic-auth.users}"
Origin: class path resource [application.yaml] - 4:12
Reason: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.List<com.tuto.properties.ApplicationProperties$User>]
Action:
Update your application's configuration
</code>
<code>Failed to bind properties under 'application.basic-auth.users' to java.util.List<com.tuto.properties.ApplicationProperties$User>:
Property: application.basic-auth.users
Value: "${basic-auth.users}"
Origin: class path resource [application.yaml] - 4:12
Reason: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.List<com.tuto.properties.ApplicationProperties$User>]
Action:
Update your application's configuration
</code>
Failed to bind properties under 'application.basic-auth.users' to java.util.List<com.tuto.properties.ApplicationProperties$User>:
Property: application.basic-auth.users
Value: "${basic-auth.users}"
Origin: class path resource [application.yaml] - 4:12
Reason: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.List<com.tuto.properties.ApplicationProperties$User>]
Action:
Update your application's configuration
Is there a solution ?