Spring Boot+MySQL特定表韩文存储突发乱码,排查字符集仍未解决
韩文编码错误排查分析
开发Spring Boot+MySQL项目时,某特定表突然出现韩文文本编码错误,此前韩文存储正常。已确认MySQL字符集配置无误,甚至重建表后问题仍存在。
乱码数据示例
1,ãããããã,ãã,1729758442950_스크린샷 2024-08-27 211441.png,1 2,ãããããã,ãã,1729759803302_스크린샷 2024-08-27 211441.png,1
MySQL字符集配置
+--------------------------+---------------------------------------------------------+ | Variable_name | Value | +--------------------------+---------------------------------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8mb3 | | character_sets_dir | C:\Program Files\MySQL\MySQL Server 8.0\share\charsets\ | +--------------------------+---------------------------------------------------------+ 8 rows in set (0.00 sec) mysql> SHOW VARIABLES LIKE 'collation%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_0900_ai_ci | | collation_database | utf8mb4_unicode_ci | | collation_server | utf8mb4_unicode_ci | +----------------------+--------------------+
表结构
self_intro | CREATE TABLE `self_intro` ( `id` bigint NOT NULL AUTO_INCREMENT, `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `content` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `image_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `user_id` bigint DEFAULT NULL, PRIMARY KEY (`id`), KEY `FKc409uoed65kpyxaq026593lp4` (`user_id`), CONSTRAINT `FKc409uoed65kpyxaq026593lp4` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
HEX查询结果
+------------------------------+--------------------------+ | title_hex | content_hex | +------------------------------+--------------------------+ | C3ACC2A0C29CC3ABC2B0C29C2F2F | C3A3C285C287C3A3C285C287 | +------------------------------+--------------------------+ 1 row in set (0.01 sec)
服务端代码
public void createSelfIntroduction(SelfIntroDto selfIntroDto, String userEmail, MultipartFile file) throws IOException { User user = userRepository.findByEmail(userEmail) // email .orElseThrow(() -> new RuntimeException("User not found with email: " + userEmail)); String imageUrl = saveFile(file); // file SelfIntro selfIntroduction = new SelfIntro(); selfIntroduction.setTitle(selfIntroDto.getTitle()); selfIntroduction.setContent(selfIntroDto.getContent()); selfIntroduction.setImageUrl(imageUrl); // save url selfIntroduction.setUser(user); System.out.println(selfIntroDto.getTitle()); selfIntroRepository.save(selfIntroduction); }
控制器代码
@PostMapping(consumes = "multipart/form-data") @Secured("ROLE_STUDENT") public ResponseEntity<String> createSelfIntroduction( @RequestPart(value = "title") String title, @RequestPart(value = "content") String content, @RequestPart(value = "file", required = false) MultipartFile file, HttpServletRequest request) { try { String userEmail = extractUserEmailFromJwt(request); SelfIntroDto selfIntroDto = new SelfIntroDto(); selfIntroDto.setTitle(title); selfIntroDto.setContent(content); User user = userRepository.findByEmail(userEmail) .orElseThrow(() -> new RuntimeException("User not found with email: " + userEmail)); selfIntroDto.setUserName(user.getName()); selfIntroDto.setUserSchool(user.getSchool()); selfIntroService.createSelfIntroduction(selfIntroDto, userEmail, file); return ResponseEntity.ok("Self Introduction created successfully"); } catch (Exception e) { return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Failed to create self introduction: " + e.getMessage()); } }
可能的原因分析
1. Multipart请求参数编码解析错误
控制器通过@RequestPart接收title和content时,Spring Boot默认对multipart/form-data类型的字符串参数可能使用ISO-8859-1编码解析,而非UTF-8。当前端传递UTF-8编码的韩文时,被错误解码后再转存到数据库,就会生成类似ãããããã的乱码。
从HEX结果来看,存储的字节序列(如C3AC)符合“UTF-8字节被当作ISO-8859-1解码,再重新编码为UTF-8”的特征——原本的韩文UTF-8字节被错误解析为乱码字符,再以UTF-8存储就会导致二次编码错误。
2. Spring Boot编码配置缺失
若未在配置文件中强制指定全局字符编码,Spring Boot处理请求时可能依赖系统默认编码(非UTF-8),导致参数解析阶段出现编码偏差。需检查application.properties或application.yml中是否配置:
spring.http.encoding.charset=UTF-8 spring.http.encoding.force=true spring.http.encoding.enabled=true spring.servlet.multipart.enabled=true
3. JDBC连接URL编码参数遗漏
尽管MySQL全局字符集配置为utf8mb4,但JDBC连接URL若未明确指定编码参数,可能导致连接时的编码协商异常。需确保URL包含以下参数:
jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=UTC
4. 控制台输出验证辅助判断
服务端代码中打印了selfIntroDto.getTitle(),可直接观察控制台输出:
- 若控制台输出为乱码:说明参数在控制器接收阶段就已编码错误,重点排查请求解析的编码配置;
- 若控制台输出正常:说明问题出在数据库存储环节,需再次确认JDBC连接参数或通过
ALTER TABLE self_intro CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci强制转换表字符集。
内容的提问来源于stack exchange,提问作者kaidey
相关产品推荐
相关产品推荐

