前言
來(lái)啦老鐵界睁!
筆者學(xué)習(xí)Spring Boot有一段時(shí)間了,附上Spring Boot系列學(xué)習(xí)文章旭寿,歡迎取閱捷枯、賜教:
- 5分鐘入手Spring Boot;
- Spring Boot數(shù)據(jù)庫(kù)交互之Spring Data JPA;
- Spring Boot數(shù)據(jù)庫(kù)交互之Mybatis;
- Spring Boot視圖技術(shù);
- Spring Boot之整合Swagger;
- Spring Boot之junit單元測(cè)試踩坑;
- 如何在Spring Boot中使用TestNG;
- Spring Boot之整合logback日志;
- Spring Boot之整合Spring Batch:批處理與任務(wù)調(diào)度;
- Spring Boot之整合Spring Security: 訪問(wèn)認(rèn)證;
- Spring Boot之整合Spring Security: 授權(quán)管理;
- Spring Boot之多數(shù)據(jù)庫(kù)源:極簡(jiǎn)方案;
- Spring Boot之使用MongoDB數(shù)據(jù)庫(kù)源;
- Spring Boot之多線程、異步:@Async;
- Spring Boot之前后端分離(一):Vue前端;
- Spring Boot之前后端分離(二):后端远豺、前后端集成;
- Spring Boot之前后端分離(三):登錄奈偏、登出、頁(yè)面認(rèn)證;
- Spring Boot之面向切面編程:Spring AOP;
- Spring Boot之集成Redis(一):Redis初入門(mén);
- Spring Boot之集成Redis(二):集成Redis;
- Spring Boot之集成Redis(三):Spring Cache + Redis;
- Spring Boot之文件上傳憋飞、下載;
最近在憋Spring Boot應(yīng)用的的一個(gè)大招霎苗,暫時(shí)還未能完成文章的編寫(xiě)姆吭,今天就來(lái)介紹一個(gè)小小的知識(shí)點(diǎn)吧:
-
如何解決Spring Boot中的中文亂碼問(wèn)題榛做?
整體步驟
- 編寫(xiě)返回內(nèi)容包含中文的API;
- 中文亂碼演示;
- 解決中文亂碼:(方法一)检眯;
- 解決中文亂碼:(方法二)厘擂;
- 解決中文亂碼:(方法三)- 全局解決中文亂碼問(wèn)題;
- 中文正常顯示演示锰瘸;
- 中文亂碼原因分析刽严;
1. 編寫(xiě)返回內(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返回中倒脓,英文正常顯示,而中文卻亂碼了含思!原因先不分析崎弃,我們先來(lái)看看怎么解決!
3. 解決中文亂碼:(方法一)含潘;
如何解決呢饲做,非常簡(jiǎn)單,修改一下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;
}
原理非常簡(jiǎn)單遏弱,就是在返回中的頭部信息中指定字符集為UTF-8盆均,親測(cè)有效!
修復(fù)中文亂碼
指定字符集為UTF-8
4. 解決中文亂碼:(方法二)腾窝;
這種辦法更為簡(jiǎn)單缀踪,比第一種還簡(jiǎn)單,只需要在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;
}
這種方式同樣可以解決中文亂碼問(wèn)題驴娃,親測(cè)有效!
5. 解決中文亂碼:(方法三)- 全局解決中文亂碼問(wèn)題循集;
上述解決中文亂碼的2種方式固然簡(jiǎn)單唇敞,但需要一個(gè)一個(gè)API添加,這不符合咱們的氣質(zhì)啊咒彤,正確的姿勢(shì)應(yīng)該是:全局解決中文亂碼問(wèn)題疆柔!
在config包內(nèi)新建CharsetConfig.java類(lèi)(類(lèi)名不限,不是非得CharsetConfig)镶柱,在該配置類(lèi)中寫(xiě)入代碼:
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ě)完成后歇拆,刪除(方法一)和(方法二)的支持代碼后鞋屈,重啟項(xiàng)目范咨,中文支持已經(jīng)變成全局生效啦,親測(cè)有效厂庇!
6. 中文正常顯示演示渠啊;
中文正常顯示演示
7. 中文亂碼原因分析;
1). 借用第三步解決亂碼問(wèn)題的代碼权旷,稍微做一下修改替蛉,打印出修改前的字符集:
@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)目并訪問(wèn)API后:
中文亂碼原因
原因找到了,原來(lái)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)目中中文亂碼的問(wèn)題:
-
API單獨(dú)設(shè)置字符集艇纺;
-
全局設(shè)置字符集怎静;
要我說(shuō),肯定是全局設(shè)置字符集更香啊黔衡,您說(shuō)呢蚓聘?
如果本文對(duì)您有幫助,麻煩點(diǎn)贊盟劫、關(guān)注夜牡!
謝謝!