Spring Boot配置属性的未解析的占位符验证

时间:2017-04-19 10:39:15

标签: spring validation spring-boot configuration spring-boot-configuration

给定一些具有无法解析的占位符的应用程序配置,例如以下application.yml

my:
  thing: ${missing-placeholder}/whatever

当我使用@Value注释时,配置文件中的占位符将得到验证,因此在这种情况下:

package com.test;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class PropValues {
    @Value("${my.thing}") String thing;
    public String getThing() { return thing; }
}

我得到IllegalArgumentException: Could not resolve placeholder 'missing-placeholder' in value "${missing-placeholder}/whatever"。这是因为该值是由AbstractBeanFactory.resolveEmbeddedValue直接设置的,并且没有任何内容可以捕获PropertyPlaceholderHelper.parseStringValue抛出的异常

但是,为了转向@ConfigurationProperties样式,我注意到缺少此验证,例如在这种情况下:

package com.test;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties(prefix = "my")
public class Props {
    private String thing;
    public String getThing() { return thing; }    
    public void setThing(String thing) { this.thing = thing; }
}

没有例外。我可以看到PropertySourcesPropertyValues.getEnumerableProperty使用评论// Probably could not resolve placeholders, ignore it here捕获异常,并将无效值收集到其内部地图中。后续数据绑定不会检查未解析的占位符。

我检查过只是将@Validated@Valid注释应用于类和字段时没有帮助。

有没有办法保留在ConfigurationProperties绑定的未解析占位符上抛出异常的行为?

3 个答案:

答案 0 :(得分:0)

显然没有更好的解决方案。至少这比afterPropertiesSet()更好。

@Data
@Validated // enables javax.validation JSR-303
@ConfigurationProperties("my.config")
public static class ConfigProperties {
    // with @ConfigurationProperties (differently than @Value) there is no exception if a placeholder is NOT RESOLVED. So manual validation is required!
    @Pattern(regexp = ".*\$\{.*", message = "unresolved placeholder")
    private String uri;
    // ...
}

更新:第一次我遇到了正则表达式错误。以便匹配整个输入(不只是java.util.regex.Matcher#find())。

答案 1 :(得分:0)

传递 @Pattern 注释的正确正则表达式是 ^(?!\\$\\{).+

@Validated
@ConfigurationProperties("my.config")
public class ConfigProperties {
    
    @Pattern(regexp = "^(?!\\$\\{).+", message = "unresolved placeholder")
    private String uri;
    // ...
}

答案 2 :(得分:-1)

我在10分钟前就遇到了同样的问题! 尝试在配置中添加此bean:

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
        return propertySourcesPlaceholderConfigurer;
    }