Can't read yaml's complex object using @ConfigurationProperties. Integer cannot be cast to String

℡╲_俬逩灬. 提交于 2019-12-11 14:40:16

问题


I'm trying to read this yml file

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

and put into this class. (I'm using Lombok and 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;
}

But I got this error.

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

If I change TreeMap<Integer, Bound> to TreeMap<String, Bound> it works fine. But I really need to use Integer. It seems like TreeMap's key (in this case: 1234) is being cast to String. I don't know why.

It was fine when TreeMap<Integer, Bound> was TreeMap<Integer, Integer>, and yml was like this.

dist-price:
  1234: 4567

EDIT: I tried Spring Boot v1.5.9.RELEASE, but no luck.


回答1:


I created a sample project from the question: https://github.com/izeye/so-48071057

and confirmed the exception is thrown from this line: https://github.com/spring-projects/spring-boot/blob/1.5.x/spring-boot/src/main/java/org/springframework/boot/bind/RelaxedDataBinder.java#L328

As you can see, key is typed as String and it's the root cause of the exception. I'm not sure this is legit usage or not as I never thought about Integer key for it.




回答2:


This has nothing to do with @ConfigurationProperties but the way YAML handle keys. Keys in YAML are String by default so if you really want to use integer there you have to force it somehow.

There are several documented ways to do this, quoting is supposed to work but didn't work for me ('1234' gave me back 234!). Forcing an integer using !!int works

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


来源:https://stackoverflow.com/questions/48071057/cant-read-yamls-complex-object-using-configurationproperties-integer-cannot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!