【问题标题】:Unable to bind map with complex key from spring boot yaml file using @ConfigurationProperties无法使用 @ConfigurationProperties 将映射与来自 Spring Boot yaml 文件的复杂键绑定
【发布时间】:2017-11-16 19:45:59
【问题描述】:

我正在尝试使用 spring boot 和 @ConfigurationProperties 注释将带有复杂键的映射从 spring yaml 配置文件解组到 java.util.Map。有很多关于带有简单键的地图的例子,比如

map: 
  key: value

甚至是带有简单键和复杂值的映射,例如

map:
  key: {firstPartOfComplexValue: alpha, secondPartOfComplexValue: beta}

我已经测试了上述两个示例 - 效果很好。

现在我需要一个复杂的地图键:

map:
  ? {firstPartOfAKey: someValue1, secondPartOfAKey: someValue2}: value

这种解组的结果是一张空地图。 请你告诉我我做错了什么 提前致谢

这是我的代码:

application.yml

custom:
  users:
    ? {firstPartOfAKey: hello, secondPartOfAKey: world} : tom

bean 解组

@Component
@ConfigurationProperties("custom")
  public class MyBean {
    private Map<Key, String> users = new HashMap<>();

    public Map<Key, String> getUsers() {
      return users;
    }

    public void setUsers(Map<Key, String> users) {
      this.users = users;
    }

    @Override
    public String toString() {
      return users.toString();
    }

    public static class Key {
      private String firstPartOfAKey;
      private String secondPartOfAKey;

      @Override
      public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Key key = (Key) o;
        return Objects.equals(firstPartOfAKey, key.firstPartOfAKey) &&
                Objects.equals(secondPartOfAKey, key.secondPartOfAKey);
      }

      @Override
      public int hashCode() {
        return Objects.hash(firstPartOfAKey, secondPartOfAKey);
      }

      public String getFirstPartOfAKey() {
        return firstPartOfAKey;
      }

      public void setFirstPartOfAKey(String firstPartOfAKey) {
        this.firstPartOfAKey = firstPartOfAKey;
      }

      public String getSecondPartOfAKey() {
        return secondPartOfAKey;
      }

      public void setSecondPartOfAKey(String secondPartOfAKey) {
        this.secondPartOfAKey = secondPartOfAKey;
      }

      @Override
      public String toString() {
        return String.format("firsPartOfKey: '%s', secondPartOfKey: '%s'", firstPartOfAKey, secondPartOfAKey);
      }
    }
}

java 配置(它是空的)

@Configuration
@ComponentScan(basePackages = {"com"})
@EnableAutoConfiguration
@EnableConfigurationProperties
public class Config {
}

单元测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Config.class})
public class TestProps {

    @Autowired
    private MyBean myBean;

    @Test
    public void testYamlPropsLoad() {
      System.out.println(myBean);
    }
}

测试仅对具有复杂键的地图打印“{}”。其他地图(带有简单键)运行良好。

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    如果您的测试没有任何异常地执行,您的MyBean 的绑定似乎根本不会被处理,通常应该有一个异常,例如:

    绑定到目标 {} 失败:

    属性:custom.null 值:{{firstPartOfAKey=hello, secondPartOfAKey=world}=tom} 原因:转换属性值失败 'java.lang.String' 类型到所需类型 'com.example.MyBean$Key' 对于属性“空”;嵌套异常是 java.lang.IllegalStateException:无法转换类型的值 'java.lang.String' 到所需类型'com.example.MyBean$Key':否 找到匹配的编辑器或转换策略

    显然解析器无法处理复杂的键,并且正在解释键 null 和值 {firstPartOfAKey=hello, secondPartOfAKey=world}=tom

    也许您可以通过实现custom editor / converter 找到另一种处理配置的方法。

    【讨论】:

    • 感谢您的回答。根本没有任何异常(甚至没有任何警告),只是空地图。但是,当我在 yaml 文件和 MyBean 中交换键和值(因此键变为字符串,值变为复杂类型)时,一切正常。似乎这是springboot中的一个错误。 Yaml 文件已通过在线验证器检查,并且正确。我将尝试通过建议的自定义编辑器/转换器来解决这个问题。谢谢。
    • 不客气。我不知道这是否是一个错误,或者它是否打算不支持复杂的键,而且在你的情况下没有例外是很奇怪的。不过,请尝试使用自定义转换器。 :)
    猜你喜欢
    • 2019-07-08
    • 2020-02-16
    • 2019-03-03
    • 2018-08-22
    • 2022-11-14
    • 2021-11-11
    • 2017-02-17
    • 2019-01-02
    • 2016-03-03
    相关资源
    最近更新 更多