问题场景
application.yml 文件在读取纯数字的时候会将0开头的数字自动转换成8进制,场景如下:
- application.yml
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
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
sso:
login:
username: heiheiha
password: '00001001'