mysqlspring-bootutf-8

It seems that the characters are getting corrupted when stored in the database


I'm working on a project with Spring Boot and MySQL, and I’ve been storing data without any issues. However, in one specific table, data suddenly starts saving with encoding errors only for Korean text. It used to save Korean characters just fine. I've double-checked that the MySQL character set is correct, and I've even recreated the table, but the issue persists.

1,ãããããã,ãã,1729758442950_스크린샷 2024-08-27 211441.png,1

2,ãããããã,ãã,1729759803302_스크린샷 2024-08-27 211441.png,1
+--------------------------+---------------------------------------------------------+
| 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 |
+----------------------+--------------------+

SHOW CREATE TABLE

 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 |

SELECT HEX(col)

+------------------------------+--------------------------+
| title_hex                    | content_hex              |
+------------------------------+--------------------------+
| C3ACC2A0C29CC3ABC2B0C29C2F2F | C3A3C285C287C3A3C285C287 |
+------------------------------+--------------------------+
1 row in set (0.01 sec)

project code server

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);
    }

controller

 @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());
        }
    }

Why might this be happening?


Solution

  • Resolved by adding WebMvcConfig code.

    @Configuration
    
    public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)
                  .mediaType("json", MediaType.APPLICATION_JSON)
                  .mediaType("text", MediaType.TEXT_PLAIN)
                  .parameterName("mediaType")
                  .favorPathExtension(true);
    }
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        converters.add(new MappingJackson2HttpMessageConverter());
    }
    }