Spring Boot前缀为0的特殊配置项处理

Scroll Down

1.背景

最近在spring boot的yml配置中配置项有个0039,项目中将该值存入Redis,后续从Redis中拿出该值进行操作时发现其值已经被改变不在是0039.

2.问题原因

​ 由于spring boot在解析yml文件时会将0开头的配置项当作八进制数处理,导致原来有前缀0的值被改变。简单阅读下源码,在ConstructYamlInt类中发现了该操作执行原理:

public class ConstructYamlInt extends AbstractConstruct {
        @Override
        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")) {
                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);
        }
}

在该类中:

1、以0b开头的数字,会被当做二进制数处理
2、以0x开头的数字,会被当做十六进制数处理
3、以0开头的数字,会被当做八进制数处理

3.解决方法

code: "0039"

将该配置项用单引号或者双引号包起来当作字符串处理。