实际上,我可以从YAML文件加载/注入Map,定义如下:
# custom-auth.yaml
auth:
providers:
keycloak:
enabled: true
realmUrl: http://localhost:38087/auth/realms/my-app-realm
clientId: keycloak-client-id
clientSecret: keycloak-client-secret
logoutUrl: keycloak-logout-url
trustbuilder:
enabled: false
clientId: tb-1-client-id
clientSecret: tb-1-client-secret
logoutUrl: tb-1-logout-url
配置类定义如下:
@Data
@Configuration
@ConfigurationProperties(prefix = "auth")
@PropertySource(value="classpath:custom-auth.yaml", factory = AuthYamlFactory.class)
public class OIDCConfiguration {
private Map<String, OIDCProvider> providers;
@Data
public static class OIDCProvider {
private boolean enabled;
private String realmUrl;
private String clientId;
private String clientSecret;
private String logoutUrl;
}
}
我们需要一个工厂类来加载上面的自定义YAML文件:
public class AuthYamlFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}
测试证明它有效:
@SpringBootTest
public class OIDCConfigurationTest {
@Autowired
private OIDCConfiguration oidcConfiguration;
@Test
public void shouldReadSeparateValues() {
Map<String, OIDCConfiguration.OIDCProvider> providers = oidcConfiguration.getProviders();
assertThat(providers).containsOnlyKeys("keycloak", "trustbuilder");
assertThat(providers.get("keycloak").isEnabled()).isTrue();
assertThat(providers.get("keycloak").getClientId()).isEqualTo("keycloak-client-id");
System.out.println(providers.get("keycloak"));
}
...
}
我想知道为什么我不能实现相同的功能,但使用如下定义的application.properties
文件:
auth.providers.keycloak.enabled=true
auth.providers.keycloak.clientSecret=keycloak-client-secret
auth.providers.keycloak.clientId=keycloak-client-id
auth.providers.trustbuilder.enabled=false
auth.providers.trustbuilder.clientSecret=trustbuilder-client-secret
auth.providers.trustbuilder.clientId=trustbuilder-client-id
配置类将有所不同,因为我无法将StringMap到OIDCProvider
示例:
@Data
@Configuration
@ConfigurationProperties("auth")
public class OIDCPropertiesConfiguration {
private Map<String, String> providers;
...
}
测试类别:
@SpringBootTest
public class OIDCConfigurationTest {
@Autowired
private OIDCConfiguration oidcConfiguration;
@Autowired
private OIDCPropertiesConfiguration oidcPropertiesConfiguration;
...
@Test
public void shouldReadSeparateValuesFromPropertiesFile() {
Map<String, String> providers = oidcPropertiesConfiguration.getProviders();
assertThat(providers).containsOnlyKeys("keycloak", "trustbuilder");
assertThat(providers.get("keycloak.enabled")).isEqualTo(true);
assertThat(providers.get("keycloak.clientId")).isEqualTo("keycloak-client-id");
System.out.println(providers.get("keycloak"));
}
}
上面的测试失败了,因为我有6个这样的提供者Map,而不是2个提供者:
{
keycloak.enabled=true,
keycloak.clientSecret=keycloak-client-secret,
keycloak.clientId=keycloak-client-id,
trustbuilder.enabled=false,
trustbuilder.clientSecret=trustbuilder-client-secret,
trustbuilderclientId=trustbuilder-client-id
}
使用索引值更改application.properties
文件中的数据,如下所示:
auth.providers[0].enabled=true
auth.providers[0].clientSecret=keycloak-client-secret
auth.providers[0].clientId=keycloak-client-id
auth.providers[1].enabled=true
auth.providers[1].clientSecret=keycloak-client-secret
auth.providers[1].clientId=keycloak-client-id
没有改变结果,Map中仍然有6个条目,而不是2个。
为什么会这样呢?如何实现与YAML文件相同的功能?有线索吗?
2条答案
按热度按时间rn0zuynd1#
只是一个想法:
1.在你的属性文件中添加一个单一的属性,比如“
auth.providers
”,并将一个JSON对象作为一个包含Map上下文的字符串作为一个值。1.在代码中将该值读取为String
1.使用任何Json库将Json对象解析为map。这可以很容易地使用JsonJackson库或Gson库来完成,无论您喜欢什么。我写了自己的JsonUtils辅助工具,它是Json-Jackson库的
ObjectMapper
类的一个薄 Package 器。有了这个实用程序,你的代码会非常简单:JsonUtils
类是由我编写和维护的开源MgntUtils java库的一部分。这里是JsonUtils Javadoc,库可以作为maven artifact或从github获得(包括源代码和Javadoc)k3bvogb12#
最后,我想出了如何让它工作。开始了
1.如下定义
application.properties
文件中的值:1.创建一个配置类,如下所示:
1.让我们在一个测试类中进行测试:
当然,我们可以在Sping Boot 应用中的任何地方访问配置值。下面是它在虚拟控制器中的使用示例:
好了希望能帮上忙瞧