bigywater.tech
Spring · 180

application.yml 的坑:NO 变成 false、01234 变成 668,tab 和冒号后没空格各报什么

application.yml 里的国家代码 NO 为什么变成 false?邮编 01234 为什么变成 668?tab、冒号后没空格、重复 key 各报什么错?哪些值必须加引号?这篇把每一种写法在 Spring Boot 4.0.8 里读一遍。

NO → false
不加引号的 NO、No 读出来是字符串 "false",yes、on 是 "true"
01234 → 668
前导 0 的数字被当成八进制,1.10 读成 "1.1"
悄悄配错
冒号后没有空格且是文件最后一行时不报错,app 变成字符串 "name:demo",app.name 不存在

no / yes / on

实测 · 本机执行输出
  YAML 内容:app: ⏎   country: NO ⏎   answer: yes ⏎   switch: on ⏎   quoted: "no" ⏎   upper: No ⏎   word: nope ⏎ 
  app.country → 字符串 "false",YAML 解析出的对象类型 Boolean
  app.answer → 字符串 "true",YAML 解析出的对象类型 Boolean
  app.switch → 字符串 "true",YAML 解析出的对象类型 Boolean
  app.quoted → 字符串 "no",YAML 解析出的对象类型 String
  app.upper → 字符串 "false",YAML 解析出的对象类型 Boolean
  app.word → 字符串 "nope",YAML 解析出的对象类型 String
  这个文件里一共解析出的属性名:[app.answer, app.country, app.quoted, app.switch, app.upper, app.word]

被解析成布尔值。

数字样子的值

实测 · 本机执行输出
  YAML 内容:app: ⏎   zip: 01234 ⏎   octal: 010 ⏎   version: 1.10 ⏎   big: 1_000 ⏎   hex: 0x1F ⏎   expo: 1e3 ⏎   quotedzip: "01234" ⏎ 
  app.zip → 字符串 "668",YAML 解析出的对象类型 Integer
  app.octal → 字符串 "8",YAML 解析出的对象类型 Integer
  app.version → 字符串 "1.1",YAML 解析出的对象类型 Double
  app.big → 字符串 "1000",YAML 解析出的对象类型 Integer
  app.hex → 字符串 "31",YAML 解析出的对象类型 Integer
  app.expo → 字符串 "1000.0",YAML 解析出的对象类型 Double
  app.quotedzip → 字符串 "01234",YAML 解析出的对象类型 String
  这个文件里一共解析出的属性名:[app.big, app.expo, app.hex, app.octal, app.quotedzip, app.version, app.zip]

前导 0、1.10、0x、1e3 都被改写。

tab 缩进

实测 · 本机执行输出
  YAML 内容:app: ⏎ <tab>name: demo ⏎ 
  启动失败:ScannerException:while scanning for the next token / found character '\t(TAB)' that cannot start any token. (Do not use \t(TAB) for indentation)

ScannerException。

冒号后没空格

实测 · 本机执行输出
  YAML 内容:app: ⏎   name:demo ⏎   port: 80 ⏎ 
  启动失败:ScannerException:mapping values are not allowed here /  in 'reader', line 3, column 7:
  -- 只有这一行(后面没有别的行)
  YAML 内容:app: ⏎   name:demo ⏎ 
  app → 字符串 "name:demo",YAML 解析出的对象类型 String
  app.name → 字符串 (没有这个属性)
  这个文件里一共解析出的属性名:[app]

有时报错,有时悄悄配错。

重复 key

实测 · 本机执行输出
  YAML 内容:app: ⏎   name: a ⏎   name: b ⏎ 
  启动失败:DuplicateKeyException:while constructing a mapping /  in 'reader', line 2, column 3:

DuplicateKeyException。

需要引号

实测 · 本机执行输出
  YAML 内容:app: ⏎   msg: hello: world ⏎ 
  启动失败:ScannerException:mapping values are not allowed here /  in 'reader', line 2, column 13:
  -- 值以 * 开头
  YAML 内容:app: ⏎   pattern: *.jar ⏎ 
  启动失败:ScannerException:while scanning an alias /  in 'reader', line 2, column 12:
  -- 值以 @ 开头
  YAML 内容:app: ⏎   user: @demo@ ⏎ 
  启动失败:ScannerException:while scanning for the next token / found character '@' that cannot start any token. (Do not use @ for indentation)
  -- 三个值都加了双引号
  YAML 内容:app: ⏎   msg: "hello: world" ⏎   pattern: "*.jar" ⏎   user: "@demo@" ⏎ 
  app.msg → 字符串 "hello: world",YAML 解析出的对象类型 String
  app.pattern → 字符串 "*.jar",YAML 解析出的对象类型 String
  app.user → 字符串 "@demo@",YAML 解析出的对象类型 String
  这个文件里一共解析出的属性名:[app.msg, app.pattern, app.user]

冒号加空格、*、@ 开头。

空值

实测 · 本机执行输出
  YAML 内容:app: ⏎   empty: ⏎   tilde: ~ ⏎   emptystr: "" ⏎   nullword: null ⏎ 
  app.empty → 字符串 "",YAML 解析出的对象类型 String
  app.tilde → 字符串 "",YAML 解析出的对象类型 String
  app.emptystr → 字符串 "",YAML 解析出的对象类型 String
  app.nullword → 字符串 "",YAML 解析出的对象类型 String
  这个文件里一共解析出的属性名:[app.empty, app.emptystr, app.nullword, app.tilde]

四种写法都是空字符串。

列表

实测 · 本机执行输出
  YAML 内容:app: ⏎   a: [x, y] ⏎   b: ⏎     - p ⏎     - q ⏎   c: x, y ⏎ 
  app.a[0] → 字符串 "x",YAML 解析出的对象类型 String
  app.a[1] → 字符串 "y",YAML 解析出的对象类型 String
  app.b[0] → 字符串 "p",YAML 解析出的对象类型 String
  app.b[1] → 字符串 "q",YAML 解析出的对象类型 String
  app.c → 字符串 "x, y",YAML 解析出的对象类型 String
  这个文件里一共解析出的属性名:[app.a[0], app.a[1], app.b[0], app.b[1], app.c]

方括号与短横线写法展开成下标属性。

分步演示

YamlPitfalls
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动(Spring Boot 4.0.8 的 spring-boot-starter,SnakeYAML 随 Boot 解析;每个情形写一个 .yml 文件,用 spring.config.location 指给应用,读 Environment 里的属性,同时读取 PropertySource 中 YAML 解析出的原始对象的类型)
    • 没有验证:多文档 YAML 与 spring.config.activate.on-profile;逗号分隔的字符串绑定到 List 字段时是否拆成多个元素(只看了 Environment 里的字符串);YAML 锚点和别名的合法用法;SnakeYAML 的 YAML 1.1 与 1.2 差异的官方说明;.properties 文件里同样的值有没有这些问题;IDE 对这些写法的提示
    京ICP备2026067502号-1京公网安备11010502063487号