Я пытаюсь прочитать этот yml файл

dist-price:
  1234:
    foo: 4567
    bar: false

И поместить в этот класс. (Я использую Lombok и Spring Boot v1.5.4.RELEASE)

@Repository
@ConfigurationProperties
@Data
@NoArgsConstructor
public class WebConfigProperty {
    @NonNull
    private TreeMap<Integer, Bound> distPrice;
}

@Data
@NoArgsConstructor
public class Bound {
    @NonNull
    private Integer foo;

    @NonNull
    private Boolean bar;
}

Но я получил эту ошибку.

Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at java.lang.String.compareTo(Unknown Source)
    at java.util.TreeMap.getEntry(Unknown Source)
    at java.util.TreeMap.get(Unknown Source)
    at org.springframework.boot.bind.RelaxedDataBinder.isBlanked(RelaxedDataBinder.java:328)
    at org.springframework.boot.bind.RelaxedDataBinder.initializePath(RelaxedDataBinder.java:283)
    at org.springframework.boot.bind.RelaxedDataBinder.normalizePath(RelaxedDataBinder.java:259)
    at org.springframework.boot.bind.RelaxedDataBinder.modifyProperty(RelaxedDataBinder.java:240)
    at org.springframework.boot.bind.RelaxedDataBinder.modifyProperties(RelaxedDataBinder.java:155)
    at org.springframework.boot.bind.RelaxedDataBinder.doBind(RelaxedDataBinder.java:128)
    at org.springframework.validation.DataBinder.bind(DataBinder.java:740)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:272)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:240)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:329)
    ... 73 common frames omitted

Если я изменю TreeMap<Integer, Bound> на TreeMap<String, Bound>, все будет нормально. Но мне действительно нужно использовать Integer. Похоже, что ключ TreeMap (в данном случае: 1234) приводится к String. Не знаю почему.

Было хорошо, когда TreeMap<Integer, Bound> был TreeMap<Integer, Integer>, а yml был таким.

dist-price:
  1234: 4567

РЕДАКТИРОВАТЬ: Я попробовал Spring Boot v1.5.9.RELEASE, но безуспешно.

0
user2652379 3 Янв 2018 в 07:12

2 ответа

Лучший ответ

Я создал образец проекта из вопроса: https://github.com/izeye/so-48071057

И подтвердил, что исключение выбрано из этой строки: https://github.com/spring-projects/spring-boot/blob/1.5.x/spring-boot/src/main/java/ org / springframework / boot / bind / RelaxedDataBinder.java # L328

Как видите, key набирается как String и является основной причиной исключения. Я не уверен, что это законное использование или нет, поскольку я никогда не думал о ключе Integer для него.

1
Johnny Lim 8 Янв 2018 в 14:46

Это не имеет ничего общего с @ConfigurationProperties, но с тем, как YAML обрабатывает ключи. Ключи в YAML по умолчанию - String, поэтому, если вы действительно хотите использовать здесь целое число, вам нужно как-то принудительно его использовать.

Есть несколько задокументированных способов сделать это, цитирование должно работать, но у меня не работает («1234» вернул мне 234!). Принуждение к целому числу с помощью !!int работает

dist-price:
  !!int 1234:
    foo: 4567
    bar: false
1
Stephane Nicoll 4 Янв 2018 в 08:07