【问题标题】:Unresolved Placeholder Validation for Spring Boot Configuration PropertiesSpring Boot 配置属性的未解决占位符验证
【发布时间】:2017-09-15 13:01:12
【问题描述】:

给定一些具有不可解析占位符的应用程序配置,如以下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 绑定的未解析占位符上引发异常的行为?

【问题讨论】:

  • 您应该在课堂上使用@Validated,在现场使用@NotNull@NotEmpty,并且要进行验证,您必须在类路径上使用JSR-303 验证器,例如@987654338 @。仅添加注释 @Validation 不会产生任何结果。
  • 有人找到解决方案了吗?

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    显然没有更好的解决方案。至少这比 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())。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 很好的发现,但实际上这是相反问题的解决方案。我不想隐藏错误,我想保留它。
      • 您必须手动使属性类实现InitializingBean 并覆盖afterPropertiesSet() 方法,您可以通过反射检查每个字段的值并在它们为空时抛出异常。跨度>
      • 这听起来不是很优雅,除了属性不会以 null 结尾之外,它们的占位符值仍然嵌入在字符串中。
      • 是的,我同意,不是很优雅。如果我找到更好的方法,我会告诉你。
      • 我不敢相信 afterPropertiesSet() 是我们拥有的最好的:'(
      猜你喜欢
      • 1970-01-01
      • 2014-07-16
      • 2014-03-23
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 2016-02-22
      • 2018-01-23
      • 2023-01-31
      相关资源
      最近更新 更多