Отображение списка в Yaml для списка объектов в Spring Загрузка
В моем загрузочном приложении Spring у меня есть файл конфигурации application.yaml со следующим контентом. Я хочу, чтобы он был введен как объект конфигурации со списком конфигураций каналов:
available-payment-channels-list:
xyz: "123"
channelConfigurations:
-
name: "Company X"
companyBankAccount: "1000200030004000"
-
name: "Company Y"
companyBankAccount: "1000200030004000"
И объект @Configuration Я хочу быть заполнен списком объектов PaymentConfiguration:
@ConfigurationProperties(prefix = "available-payment-channels-list")
@Configuration
@RefreshScope
public class AvailableChannelsConfiguration {
private String xyz;
private List<ChannelConfiguration> channelConfigurations;
public AvailableChannelsConfiguration(String xyz, List<ChannelConfiguration> channelConfigurations) {
this.xyz = xyz;
this.channelConfigurations = channelConfigurations;
}
public AvailableChannelsConfiguration() {
}
// getters, setters
@ConfigurationProperties(prefix = "available-payment-channels-list.channelConfigurations")
@Configuration
public static class ChannelConfiguration {
private String name;
private String companyBankAccount;
public ChannelConfiguration(String name, String companyBankAccount) {
this.name = name;
this.companyBankAccount = companyBankAccount;
}
public ChannelConfiguration() {
}
// getters, setters
}
}
Я вставляю это как обычный bean с @Autowired конструктором. Значение xyz заполнено правильно, но когда Spring пытается проанализировать yaml в списке объектов, я получаю
nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.String] to required type
[io.example.AvailableChannelsConfiguration$ChannelConfiguration]
for property 'channelConfigurations[0]': no matching editors or
conversion strategy found]
Любые подсказки, что здесь не так?
Ответы
Ответ 1
Причина должна быть где-то в другом месте. Используя только Spring Boot 1.2.2 из коробки без конфигурации, он просто работает. Посмотрите на это репо - вы можете заставить его сломаться?
https://github.com/konrad-garus/so-yaml
Вы уверены, что файл YAML выглядит так, как вы вставляете? Нет лишних пробелов, символов, специальных символов, неправильного ввода или что-то в этом роде? Возможно, у вас есть другой файл в другом месте пути поиска, который используется вместо того, который вы ожидаете?
Ответ 2
- Вам не нужны конструкторы
- Вам не нужно комментировать внутренние классы
-
RefreshScope
имеют некоторые проблемы при использовании с @Configuration
. См. эту проблему github
Измените свой класс следующим образом:
@ConfigurationProperties(prefix = "available-payment-channels-list")
@Configuration
public class AvailableChannelsConfiguration {
private String xyz;
private List<ChannelConfiguration> channelConfigurations;
// getters, setters
public static class ChannelConfiguration {
private String name;
private String companyBankAccount;
// getters, setters
}
}
Ответ 3
У меня было много проблем с этим. Наконец я узнал, что это за заключительная сделка.
Обратившись к ответу @Gokhan Oner, если у вас есть свой класс обслуживания и POJO, представляющий ваш объект, ваш конфигурационный файл YAML приятный и скудный, если вы используете аннотацию @ConfigurationProperties, вам нужно явно получить объект для способный использовать его. Например:
@ConfigurationProperties(prefix = "available-payment-channels-list")
//@Configuration <- you don't specificly need this, instead you're doing something else
public class AvailableChannelsConfiguration {
private String xyz;
//initialize arraylist
private List<ChannelConfiguration> channelConfigurations = new ArrayList<>();
public AvailableChannelsConfiguration() {
for(ChannelConfiguration current : this.getChannelConfigurations()) {
System.out.println(current.getName()); //TADAAA
}
}
public List<ChannelConfiguration> getChannelConfigurations() {
return this.channelConfigurations;
}
public static class ChannelConfiguration {
private String name;
private String companyBankAccount;
}
}
И вот вы здесь. Это просто, как черт, но мы должны знать, что мы должны назвать объект getter. Я ждал при инициализации, желая, чтобы объект строился со значением, но нет. Надеюсь, это поможет:)
Ответ 4
Я ссылался на эту статью и многие другие, и не нашел четкого краткого ответа на помощь. Я предлагаю свое открытие, получив некоторые ссылки из этого потока, в следующем:
Spring -Boot version: 1.3.5.RELEASE
Spring -Core version: 4.2.6.RELEASE
Управление зависимостями: Brixton.SR1
Ниже приведена соответствующая выдержка yaml:
tools:
toolList:
-
name: jira
matchUrl: http://someJiraUrl
-
name: bamboo
matchUrl: http://someBambooUrl
Я создал инструмент Tools.class:
@Component
@ConfigurationProperties(prefix = "tools")
public class Tools{
private List<Tool> toolList = new ArrayList<>();
public Tools(){
//empty ctor
}
public List<Tool> getToolList(){
return toolList;
}
public void setToolList(List<Tool> tools){
this.toolList = tools;
}
}
Я создал Tool.class:
@Component
public class Tool{
private String name;
private String matchUrl;
public Tool(){
//empty ctor
}
public String getName(){
return name;
}
public void setName(String name){
this.name= name;
}
public String getMatchUrl(){
return matchUrl;
}
public void setMatchUrl(String matchUrl){
this.matchUrl= matchUrl;
}
@Override
public String toString(){
StringBuffer sb = new StringBuffer();
String ls = System.lineSeparator();
sb.append(ls);
sb.append("name: " + name);
sb.append(ls);
sb.append("matchUrl: " + matchUrl);
sb.append(ls);
}
}
Я использовал эту комбинацию в другом классе через @Autowired
@Component
public class SomeOtherClass{
private Logger logger = LoggerFactory.getLogger(SomeOtherClass.class);
@Autowired
private Tools tools;
/* excluded non-related code */
@PostConstruct
private void init(){
List<Tool> toolList = tools.getToolList();
if(toolList.size() > 0){
for(Tool t: toolList){
logger.info(t.toString());
}
}else{
logger.info("*****----- tool size is zero -----*****");
}
}
/* excluded non-related code */
}
И в моих журналах было зарегистрировано имя и соответствующий URL-адрес. Это было разработано на другой машине, и поэтому мне пришлось перепечатать все вышеизложенное, поэтому, пожалуйста, простите меня заранее, если я нечаянно ошибся.
Я надеюсь, что этот комментарий консолидации полезен для многих, и я благодарю предыдущих участников этой темы!