ymal解析问题:Configuration property name ‘-index‘ is not valid

ymal解析问题:Configuration property name ‘-index’ is not valid

问题由来

启动canal adapter项目,配置好了同步mysql 到elasticseach的同步配置文件,如下所示,发现一直报错

dataSourceKey: defaultDS
destination: pay_parent_0
groupId: g1
esMapping:
  _index: pay_parent_0
  _id: id
  sql: select id, user_id, status, creator, create_time, updater, update_time, deleted, tenant_id from pay_parent_0 as a
  etlCondition: where a.id={}
  commitBatch: 3000

报错内容如下

Caused by: org.springframework.boot.context.properties.source.InvalidConfigurationPropertyNameException: Configuration property name '-index' is not valid
	at org.springframework.boot.context.properties.source.InvalidConfigurationPropertyNameException.throwIfHasInvalidChars(InvalidConfigurationPropertyNameException.java:51) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.context.properties.source.ConfigurationPropertyName.append(ConfigurationPropertyName.java:189) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.lambda$bindBean$4(Binder.java:335) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:73) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:62) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:54) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at org.springframework.boot.context.properties.bind.Binder.lambda$null$5(Binder.java:342) ~[spring-boot-2.0.1.RELEASE.jar:2.0.1.RELEASE]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1631) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:127) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:502) ~[na:na]

问题分析

报错内容为-index 的属性key不合法,找到报错的位置校验代码,org.springframework.boot.context.properties.source.ConfigurationPropertyName.ElementValidator#isValidChar这里不允许以’-'开头的key值。

public static boolean isValidChar(char ch, int index) {
    return isAlpha(ch) || isNumeric(ch) || index != 0 && ch == '-';
}

但是我配置文件配置的是 _index,明显对不上,所以应该是yaml解析时做了转换。于是开始debug跟踪,发现yaml解析bean时有这么一段方法,该方法会将所有的key中的下划线转成横杠,那应该是这个问题。

BeanProperty(String name, ResolvableType declaringClassType) {
    this.name = BeanPropertyName.toDashedForm(name);
    this.declaringClassType = declaringClassType;
}

    public static String toDashedForm(String name, int start) {
        StringBuilder result = new StringBuilder();
        char[] chars = name.replace("_", "-").toCharArray(); // 下环线转化

        for(int i = start; i < chars.length; ++i) {
            char ch = chars[i];
            if (Character.isUpperCase(ch) && result.length() > 0 && result.charAt(result.length() - 1) != '-') {
                result.append("-");
            }

            result.append(Character.toLowerCase(ch));
        }

        return result.toString();
    }

问题解决

解决方式有两种思路,一个是修改配置类,去掉下划线开头的key,这样就不会转换成“-”,所以这个得需要修改代码。修改配置类的get方案,因为yaml的bean解析是从get set方法解析处属性的值,例如get_index会解析处_index属性,这里需要将get_index方法名修改成getIndex _index 修改成index属性。如下的修改

ymal解析问题:Configuration property name ‘-index‘ is not valid_第1张图片

另外一种思路是修改springboot 和spring core 版本,因为高版本是兼容这种下划线开头的key,找到相同的高本本解析bean位置代码,发现已经去掉了对下环线的替代, char[] chars = name.replace(“_”, “-”).toCharArray(); 这行方法已经去掉了。这个是spring2.5版本,具体升级到哪个版本,根据实际项目来操作。

    public static String toDashedForm(String name) {
        StringBuilder result = new StringBuilder(name.length());
        boolean inIndex = false;

        for(int i = 0; i < name.length(); ++i) {
            char ch = name.charAt(i);
            if (inIndex) {
                result.append(ch);
                if (ch == ']') {
                    inIndex = false;
                }
            } else if (ch == '[') {
                inIndex = true;
                result.append(ch);
            } else {
                ch = ch != '_' ? ch : 45;
                if (Character.isUpperCase(ch) && result.length() > 0 && result.charAt(result.length() - 1) != '-') {
                    result.append('-');
                }

                result.append(Character.toLowerCase(ch));
            }
        }

        return result.toString();
    }

你可能感兴趣的:(springboot,java,spring,boot)