#spring #spring-boot #yaml #configurationproperties
#spring #весенняя загрузка #yaml #свойства конфигурации
Вопрос:
Я пытаюсь загрузить исходящие свойства из конфигурации, используя комбинацию Spring @Configuration amp; @ConfigurationProperties. У меня есть POJO, который расширяет HashMap<Целое число, строка> и имеет внутри одну переменную. (См. MyConfigPojo
Ниже). Из .файл yaml, у меня такая же форма. Однако при загрузке приложения я получаю сообщение об ошибке при попытке преобразовать строку для значения по умолчанию в целое число.
@Configuration
@ConfigurationPropeties(prefix = "my-config")
public class MyConfigPojo extends HashMap<Integer, String> {
private String defaultValue;
private String getValueForIdOrDefault(int id); // this.get(id) OR ELSE defaultValue
}
В конфигурации у меня есть это:
myConfig:
1: "my first value"
23: "my 23rd value"
defaultValue: "cheese"
Что приводит к
APPLICATION FAILED TO START
Description:
Failed to bind properties under 'myPackage' to MyConfigPojo:
Property: myConfig[1]
Value: cheese
Я подумал, что это странно, поэтому я включил журналы ТРАССИРОВКИ и обнаружил это:
99 common frames omittedCaused by: java.lang.NumberFormatException: For input string: "defaultValue" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
Есть ли способ перехватить чтение этого файла или сообщить Spring, как правильно установить значения?
Комментарии:
1. Что вы пытаетесь сделать? просто хотите прочитать свойства из yaml в map правильно?
2. В принципе, у меня будет список этих сопоставлений Int -> String, каждое из которых имеет собственное значение по умолчанию, которое я хотел бы прочитать из конфигурации. например:
[{1: "firstMapValueForKey1", 4: "fistMapValaueForKey4", defaultValue: "defaultValueForFirstMap"}, {2: "secondMapValueForKey2", 9: "secondMapValueForKey9", defaultValue: "secondMapDefaultValue"}]
3. Ваша реальная проблема заключается в попытке прочитать значение карты a: b (ключ: значение), поэтому вы должны поддерживать согласованный тип ключа, изначально вы используете integer , но defaultValue равно string , поэтому вы получаете исключение NumberFormatException
4. Я знаю, что могу просто изменить тип карты и избавиться от проблемы. Я пытаюсь понять, есть ли способ не делать это таким образом. например, с помощью @ConfigurationPropetiesBinding
5. О, отлично, вы ничего не упомянули об этой аннотации @ConfigurationPropetiesBinding, о которой идет речь. В любом случае, удачи
Ответ №1:
Вы пытаетесь прочитать карту из файла .yml, для этого вам достаточно @ConfigurationProperties
аннотации, не нужны @Configuration
аннотации (при использовании spring boot). Если вы используете spring-framework, вам также понадобится @Configuration.
Используйте этот пример:
myConfig:
map:
1: "my first value"
23: "my 23rd value"
defaultValue: "cheese"
MyConfigPojo.java
package com.org;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.HashMap;
@Configuration
@ConfigurationProperties(prefix = "my-config")
public class MyConfigPojo {
private HashMap<String, String> map;
public HashMap<String, String> getMap() {
return map;
}
public void setMap(HashMap<String, String> map) {
this.map = map;
}
}
Теперь вы можете автоматически подключить этот MyConfigPojo
класс в любом месте (например, в классе контроллера) и прочитать эти ключи и значения карты.
@Autowired
MyConfigPojo pojo;
Теперь, когда вы рассмотрели ключи и значения как String
тип данных для этой карты, вы не получите NumberFormatException
.
Комментарии:
1. Полезно знать об
@Configuration
. Я знаю, что могу переключить карту с<Integer, String>
на<String, String>
, но я пытаюсь найти способ обойти это. например, используя некоторую форму @ConfigurationPropertiesBinding2. Когда я удалил
@Configuration
аннотацию, я начал получать эту ошибку `Для поля MyPOJO в mypackage требуется компонент типа ‘myPackage. MyPOJO’, который не удалось найти.3. Да, если вы используете spring boot, вам это не нужно. Весной вам это нужно.