You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot从MySQL获取越南语字符乱码问题排查

越南语字符在Spring Boot API返回时乱码的排查与解决

问题背景

我基于Spring Boot开发了一个简单API,从Docker部署的MySQL数据库中读取数据。直接在数据库执行SELECT * FROM pair;查询时,越南语字符显示正常,但API返回的越南语内容出现乱码。

数据库初始化脚本

CREATE DATABASE IF NOT EXISTS word_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GO

USE word_app;
GO

CREATE TABLE user (
  id INT NOT NULL AUTO_INCREMENT,
  display_name VARCHAR(50),
  username VARCHAR(100),
  password VARCHAR(100),
  PRIMARY KEY (id)
);
GO

CREATE TABLE category (
  id INT NOT NULL AUTO_INCREMENT,
  title VARCHAR(50),
  user_id INT NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (user_id) REFERENCES user(id)
);
GO

CREATE TABLE pair (
  id INT NOT NULL AUTO_INCREMENT,
  en VARCHAR(255),
  vi VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci,
  category_id INT NOT NULL,
  PRIMARY KEY (id),
  FOREIGN KEY (category_id) REFERENCES category(id)
);
GO

INSERT INTO pair (en, vi, category_id)
VALUES ("mediterranean", "Địa Trung Hải(adj, n)", 5);

API返回乱码示例

"data": [
        {
            "id": 42,
            "en": "mediterranean",
            "vi": "Äịa Trung Hải(adj, n)",
            "categoryId": 5
        },
        {
            "id": 43,
            "en": "stronghold",
            "vi": "pháo đài",
            "categoryId": 5
        }]

当前application.properties配置

spring.datasource.url=jdbc:mysql://localhost:3306/word_app?useUnicode=true&characterEncoding=UTF-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true


server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

spring.mvc.locale-resolver=fixed
spring.mvc.locale=vi_VN

排查与解决步骤

1. 修正JDBC URL的字符编码参数

properties文件中无需使用HTML转义字符&,直接用&拼接参数。同时针对MySQL 8.0+,补充characterSetResults=utf8mb4确保读取数据时的编码一致,修改后的URL:

spring.datasource.url=jdbc:mysql://localhost:3306/word_app?useUnicode=true&characterEncoding=utf8mb4&characterSetResults=utf8mb4&useSSL=false

2. 验证数据库连接编码

添加代码打印数据库连接的字符编码属性,确认配置是否生效:

import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.SQLException;

@Component
public class DbEncodingChecker {
    @Autowired
    private DataSource dataSource;

    public void checkEncoding() throws SQLException {
        try (Connection conn = dataSource.getConnection()) {
            String encoding = conn.getMetaData().getCharacterSet();
            System.out.println("数据库连接字符集: " + encoding);
        }
    }
}

3. 配置JPA/Hibernate编码参数

避免Hibernate覆盖连接编码设置,在application.properties中添加:

spring.jpa.properties.hibernate.connection.characterEncoding=utf8mb4
spring.jpa.properties.hibernate.connection.useUnicode=true

4. 修正Docker容器中MySQL的编码配置

Docker部署的MySQL可能默认编码不是utf8mb4,启动容器时需指定编码参数:

  • 用docker run命令启动:
docker run -e MYSQL_ROOT_PASSWORD=yourpassword -e MYSQL_CHARACTER_SET=utf8mb4 -e MYSQL_COLLATION=utf8mb4_unicode_ci mysql:8.0
  • 用docker-compose.yml配置:
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: yourpassword
      MYSQL_DATABASE: word_app
      MYSQL_CHARACTER_SET: utf8mb4
      MYSQL_COLLATION: utf8mb4_unicode_ci

5. 显式指定API响应编码

在Controller方法上明确指定响应的Content-Type编码,确保输出编码正确:

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PairController {
    @GetMapping(value = "/pairs", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<Pair> getPairs() {
        // 业务逻辑实现
    }
}

6. 重新插入测试数据

如果之前的数据是在编码配置错误时插入的,可能已存储为乱码。需删除现有数据,在正确配置完成后重新插入,确保数据本身以utf8mb4编码存储。

内容的提问来源于stack exchange,提问作者Peter Present

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 14:47:17