Spring - application.yml 数字读取错误、eg: 000001

2020-08-14 16:32:54 浏览数 (2)

问题场景

application.yml 文件在读取纯数字的时候会将0开头的数字自动转换成8进制,场景如下:

  • application.yml
代码语言:javascript复制
sso:
  login:
    username: heiheiha
    password: 00001001

通过@Value获取

代码语言:javascript复制
@Value("${sso.login.username}")
String password = "513";
问题原因

spring在读取application.yml文件时,会先判断password的类型并进行tag标注(Tag-tag:yaml.org,2002:int),然后在解析时通过不同的策略自动转换。

当数字是0开头时,自动转换成8进制

源码如下:

  • org.yaml.snakeyaml.constructor.SafeConstructor
代码语言:javascript复制
public class ConstructYamlInt extends AbstractConstruct {
    public Object construct(Node node) {
        String value = constructScalar((ScalarNode) node).toString().replaceAll("_", "");
        int sign =  1;
        char first = value.charAt(0);
        if (first == '-') {
            sign = -1;
            value = value.substring(1);
        } else if (first == ' ') {
            value = value.substring(1);
        }
        int base = 10;
        if ("0".equals(value)) {
            return Integer.valueOf(0);
        } else if (value.startsWith("0b")) {
            value = value.substring(2);
            base = 2;
        } else if (value.startsWith("0x")) {
            value = value.substring(2);
            base = 16;
        } else if (value.startsWith("0")) {//重点在这,会把0开头的int型自动转换为8进制
            value = value.substring(1);
            base = 8;
        } else if (value.indexOf(':') != -1) {
            String[] digits = value.split(":");
            int bes = 1;
            int val = 0;
            for (int i = 0, j = digits.length; i < j; i  ) {
                val  = Long.parseLong(digits[j - i - 1]) * bes;
                bes *= 60;
            }
            return createNumber(sign, String.valueOf(val), 10);
        } else {
            return createNumber(sign, value, 10);
        }
        return createNumber(sign, value, base);
    }
}

// 转换为相应进制数字
private Number createNumber(int sign, String number, int radix) {
    Number result;
    if (sign < 0) {
        number = "-"   number;
    }
    try {
        result = Integer.valueOf(number, radix);
    } catch (NumberFormatException e) {
        try {
            result = Long.valueOf(number, radix);
        } catch (NumberFormatException e1) {
            result = new BigInteger(number, radix);
        }
    }
    return result;
}
解决方法

很简单,将00001001 写成 '00001001'即可

  • application.yml
代码语言:javascript复制
sso:
  login:
    username: heiheiha
    password: '00001001'

0 人点赞