
spring boot 应用在终端运行时出现日志乱码(如 `%.s.s.s.standardservicelr` 等异常字符),而在 intellij 中正常显示,根本原因是 jvm 默认字符编码与终端环境不匹配,需显式指定 `-dfile.encoding=utf-8` 启动参数。
该问题本质是 JVM 字符编码未对齐 导致的日志渲染异常。IntelliJ 默认以 UTF-8 启动 JVM,且其内置终端已正确配置编码;而系统终端(zsh/bash)启动 Java 进程时,JVM 会依据操作系统区域设置(locale)推断 file.encoding,若 locale 非 UTF-8(例如 en_US.ISO8859-1 或未正确配置),Spring Boot 的 ANSI 彩色日志、占位符解析及 Logback 日志格式化器将无法正确解码字节流,最终表现为大量 %.S.S.S... 类似乱码——这并非真实日志内容损坏,而是日志框架(如 Logback)在编码不一致时对 MDC、pattern layout 中的转义序列和样式标记(如 %clr, %5p, %logger)错误解析所致。
✅ 推荐解决方案(立即生效)
在终端中启动 JAR 包时,强制指定 UTF-8 编码:
java -Dfile.encoding=UTF-8 -jar target/app-0.001-SNAPSHOT.jar
✅ 进阶方案:全局或项目级固化配置
-
方式 1:通过 JAVA_TOOL_OPTIONS(推荐,影响所有 java 命令)
export JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8" # 加入 ~/.zshrc 或 ~/.bash_profile 永久生效
-
方式 2:在 Maven 打包时嵌入 JVM 参数(适用于 CI/CD 或统一部署)
在 pom.xml 的 spring-boot-maven-plugin 中配置:org.springframework.boot spring-boot-maven-plugin -Dfile.encoding=UTF-8 ⚠️ 注意:此配置仅影响 mvn spring-boot:run,不影响 java -jar 直接运行。
✅ 验证是否生效
启动后检查日志首行是否含标准 Spring Boot Banner(带 ASCII 艺术字)及清晰时间戳、线程名、日志级别(如 INFO, DEBUG),而非 %.S.S.S...。也可在应用内添加测试代码确认当前编码:
System.out.println("Default charset: " + java.nio.charset.Charset.defaultCharset());
// 正常应输出:Default charset: UTF-8? 额外建议
- 确保终端本身支持 UTF-8:执行 locale 命令,确认 LANG 和 LC_ALL 均为 *.UTF-8(如 en_US.UTF-8)。若非 UTF-8,可临时设置:
export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
- 若使用 Docker,需在 Dockerfile 中同步设置:
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
总结:该问题与 Spring Boot 版本、Shell 类型(zsh/bash)或 IDE 无关,纯粹是 JVM 启动时字符集协商失败所致。最简、最可靠的做法始终是显式传入 -Dfile.encoding=UTF-8 —— 它成本极低,兼容所有 Spring Boot 版本(2.x / 3.x),且是生产环境最佳实践之一。










