Why doesn't it work?
gateway:
servers:
- local-server:
url: https://localhost:${server.port}
description: Api-Gateway-V2
v1-prefix: /api/v1
package by.afinny.apigateway.constant;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public final class GatewayMeta {
@Value("${gateway.servers}")
public List<Server> servers;
@Value("${gateway.v1-prefix}")
public String v1Prefix;
public List<Server> servers() {
return servers;
}
public String v1Prefix() {
return v1Prefix;
}
}
import io.swagger.v3.oas.models.annotations.OpenAPI31;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
public class Server {
private String url = null;
private String description = null;
private ServerVariables variables = null;
private Map<String, Object> extensions = null;
public Server() {
}
// ...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'gateway.servers' in value "${gateway.servers}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[spring-core-6.0.12.jar:6.0.12]
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-6.0.12.jar:6.0.12]
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-6.0.12.jar:6.0.12]
I tried adding some "configuration processor" as a regular dependency as per this advice, but it didn't work (should I wrap it in some "processor" tags?)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
I don't get any META-INF in my target
after a build (should I?)
Spring Boot 3, Java 17
I tried this
package by.afinny.apigateway.constant;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Setter
@ConfigurationProperties(value = "gateway")
public final class GatewayMeta {
public List<Server> servers;
public String v1Prefix;
public List<Server> servers() {
return servers;
}
public String v1Prefix() {
return v1Prefix;
}
}
# notice the camel case
gateway:
servers:
- local-server:
url: https://localhost:${server.port}
description: Api-Gateway-V2
v1Prefix: /api/v1
I get an exception. It's relatively detailed, but I still don't understand what I need to do. Update how?
ERROR 19960 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target [Bindable@2a484710 type = java.util.List<io.swagger.v3.oas.models.servers.Server>, value = 'none', annotations = array<Annotation>[[empty]], bindMethod = [null]] failed:
Property: gateway.servers[0].local-server.description
Value: "Api-Gateway-V2"
Origin: class path resource [application-prod.yml] - 53:22
Reason: The elements [gateway.servers[0].local-server.description,gateway.servers[0].local-server.url] were left unbound.
Property: gateway.servers[0].local-server.url
Value: "https://localhost:${server.port}"
Origin: class path resource [application-prod.yml] - 52:14
Reason: The elements [gateway.servers[0].local-server.description,gateway.servers[0].local-server.url] were left unbound.
Action:
Update your application's configuration
I also included @EnableConfigurationProperties
above my @SpringBootApplication
class (I accidentally found it and decided to put it just in case)
I discovered it has to do with Server
serialization: if I comment out everything related to servers, the prefix does get resolved. But why? Server
does have getters and setters
Besides, I don't want my yaml to be forced to follow that camel case. I haven't found some equivalent of @JsonProperty
for @ConfigurationProperties
(like @ConfigurationProperty
or something)
For managed complex list is suggested to use ConfigurationProperties
. I think that is your yml structure wrong.
I replicated here the case https://github.com/sbernardo/spring-issues-examples/tree/main/sof-questions-77646394
Old yml:
gateway:
servers:
- local-server:
url: https://localhost:${server.port}
description: Api-Gateway-V2
v1Prefix: /api/v1
New yml:
gateway:
servers:
- local-server:
url: https://localhost:${server.port}
description: Api-Gateway-V2
- local-server:
url: https://localhost2:${server.port}
description: Api-Gateway-V3
v1Prefix: /api/v1
As you can see there is a level that throw exception. Because in yaml you are define and array with -
simbol with only local-server
key and you are add another level on each object with fields url
and description
fields.
I think key local-server
is useless and you can remove it.
Hope this will help :)