Spring Boot中文亂碼問題解決方案:親測有效

前言

來啦老鐵!

筆者學(xué)習(xí)Spring Boot有一段時(shí)間了,附上Spring Boot系列學(xué)習(xí)文章,歡迎取閱、賜教:

  1. 5分鐘入手Spring Boot;
  2. Spring Boot數(shù)據(jù)庫交互之Spring Data JPA;
  3. Spring Boot數(shù)據(jù)庫交互之Mybatis;
  4. Spring Boot視圖技術(shù);
  5. Spring Boot之整合Swagger;
  6. Spring Boot之junit單元測試踩坑;
  7. 如何在Spring Boot中使用TestNG;
  8. Spring Boot之整合logback日志;
  9. Spring Boot之整合Spring Batch:批處理與任務(wù)調(diào)度;
  10. Spring Boot之整合Spring Security: 訪問認(rèn)證;
  11. Spring Boot之整合Spring Security: 授權(quán)管理;
  12. Spring Boot之多數(shù)據(jù)庫源:極簡方案;
  13. Spring Boot之使用MongoDB數(shù)據(jù)庫源;
  14. Spring Boot之多線程、異步:@Async;
  15. Spring Boot之前后端分離(一):Vue前端;
  16. Spring Boot之前后端分離(二):后端、前后端集成;
  17. Spring Boot之前后端分離(三):登錄、登出、頁面認(rèn)證;
  18. Spring Boot之面向切面編程:Spring AOP;
  19. Spring Boot之集成Redis(一):Redis初入門;
  20. Spring Boot之集成Redis(二):集成Redis;
  21. Spring Boot之集成Redis(三):Spring Cache + Redis;
  22. Spring Boot之文件上傳、下載;

最近在憋Spring Boot應(yīng)用的的一個(gè)大招,暫時(shí)還未能完成文章的編寫,今天就來介紹一個(gè)小小的知識(shí)點(diǎn)吧:

  • 如何解決Spring Boot中的中文亂碼問題?

整體步驟

  1. 編寫返回內(nèi)容包含中文的API;
  2. 中文亂碼演示;
  3. 解決中文亂碼:(方法一);
  4. 解決中文亂碼:(方法二);
  5. 解決中文亂碼:(方法三)- 全局解決中文亂碼問題;
  6. 中文正常顯示演示;
  7. 中文亂碼原因分析;

1. 編寫返回內(nèi)容包含中文的API;

隨便在一個(gè)Spring Boot項(xiàng)目中的controller中添加一個(gè)API,如下:

@GetMapping("/api/hello")
public JSONObject sayHello() {
    JSONObject test = new JSONObject();
    test.put("name", "dylanz");
    test.put("say", "您好");
    return test;
}

2. 中文亂碼演示;

啟動(dòng)下項(xiàng)目后,請(qǐng)求API:http://127.0.0.1:8080/api/hello

中文亂碼演示

我們會(huì)發(fā)現(xiàn),API返回中,英文正常顯示,而中文卻亂碼了!原因先不分析,我們先來看看怎么解決!

3. 解決中文亂碼:(方法一);

如何解決呢,非常簡單,修改一下API:

@GetMapping("/api/hello")
public JSONObject sayHello() {
    HttpServletResponse response = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
    assert response != null;
    response.setCharacterEncoding("UTF-8");

    JSONObject test = new JSONObject();
    test.put("name", "dylanz");
    test.put("say", "您好");
    return test;
}

原理非常簡單,就是在返回中的頭部信息中指定字符集為UTF-8,親測有效!

修復(fù)中文亂碼
指定字符集為UTF-8

4. 解決中文亂碼:(方法二);

這種辦法更為簡單,比第一種還簡單,只需要在API上指定produces即可,如:

@GetMapping(value = "/api/hello", produces = "application/json;charset=UTF-8")
public JSONObject sayHello() {
    JSONObject test = new JSONObject();
    test.put("name", "dylanz");
    test.put("say", "您好");
    return test;
}

這種方式同樣可以解決中文亂碼問題,親測有效!

5. 解決中文亂碼:(方法三)- 全局解決中文亂碼問題;

上述解決中文亂碼的2種方式固然簡單,但需要一個(gè)一個(gè)API添加,這不符合咱們的氣質(zhì)啊,正確的姿勢應(yīng)該是:全局解決中文亂碼問題!

在config包內(nèi)新建CharsetConfig.java類(類名不限,不是非得CharsetConfig),在該配置類中寫入代碼:
package com.github.dylanz666.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : dylanz
 * @since : 11/15/2020
 */
@Configuration
public class CharsetConfig extends WebMvcConfigurationSupport {
    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        return new StringHttpMessageConverter(
                StandardCharsets.UTF_8);
    }

    @Override
    public void configureMessageConverters(
            List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(responseBodyConverter());

        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat
        );
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);

        converters.add(fastConverter);
    }

    @Override
    public void configureContentNegotiation(
            ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
}

由于我使用的是fastjson,因此在configureMessageConverters中添加了fastjson對(duì)中文支持的配置代碼。

編寫完成后,刪除(方法一)和(方法二)的支持代碼后,重啟項(xiàng)目,中文支持已經(jīng)變成全局生效啦,親測有效!

6. 中文正常顯示演示;

中文正常顯示演示

7. 中文亂碼原因分析;

1). 借用第三步解決亂碼問題的代碼,稍微做一下修改,打印出修改前的字符集:
@GetMapping("/api/hello")
public JSONObject sayHello() {
    HttpServletResponse response = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
    assert response != null;
    System.out.println("Default charset: " + response.getCharacterEncoding());

    JSONObject test = new JSONObject();
    test.put("name", "dylanz");
    test.put("say", "您好");
    return test;
}
2). 再次啟動(dòng)項(xiàng)目并訪問API后:
中文亂碼原因

原因找到了,原來Spring Boot中的JSON默認(rèn)字符集是:ISO-8859-1(如果返回是純String,則字符集為UTF-8,且中文不會(huì)亂碼)。

從瀏覽器或postman上也能看出默認(rèn)的字符集設(shè)置:

默認(rèn)字符集
3). 我們解決亂碼后的字符集:
image.png

至此,我們從2個(gè)維度、3種方法,解決了Spring Boot項(xiàng)目中中文亂碼的問題:

  • API單獨(dú)設(shè)置字符集;
  • 全局設(shè)置字符集;

要我說,肯定是全局設(shè)置字符集更香啊,您說呢?

如果本文對(duì)您有幫助,麻煩點(diǎn)贊、關(guān)注!

謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容