springboot參數(shù)傳中文亂碼的解決方案
前言
本文案例來自業(yè)務部門的一個業(yè)務場景。他們的業(yè)務場景是他們部門研發(fā)了一個微服務上下文透傳組件,其透傳原理也挺簡單的,就是通過springboot攔截器把請求參數(shù)塞進threadlocal,然后下游通過threadlocal取到值,服務之間進行feign調(diào)用時,再把threadlocal的參數(shù)塞到header頭里面。這個組件一直用得好好的,突然有一天因為傳的參數(shù)值是中文,導致亂碼。他們通過嘗試下面的各種方案,都無法解決。最后就讓我們部門排查處理。
業(yè)務部門的實現(xiàn)思路
他們一開始的思路方向是參數(shù)編碼不一致導致中文亂碼。于是他們就朝這個方向努力著,于是就有了如下方案
方案一:
String value = new String("我是中文亂碼".getBytes("ISO-8859-1"),"UTF-8");
這個是常用解決字符串中文亂碼的方法之一
方案二:編寫字符編碼過濾器
@WebFilter(urlPatterns = "/*",filterName = "CharacterEncodingFilter")
public class CharacterEncodingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
filterChain.doFilter(request , response);
}
@Override
public void destroy() {
}
}
然后啟動類上加上@ServletComponentScan。@WebFilter是servlet3.0才有的注解。當然這個過濾器你還可以這么寫
public class CharacterEncodingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
filterChain.doFilter(request , response);
}
@Override
public void destroy() {
}
}
然后啟動類上加上@ServletComponentScan。@WebFilter是servlet3.0才有的注解。當然這個過濾器你還可以這么寫
public class CharacterEncodingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
filterChain.doFilter(request , response);
}
@Override
public void destroy() {
}
}
寫個bean配置類,如下
@Bean
public FilterRegistrationBean registerAuthFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CharacterEncodingFilter();
registration.addUrlPatterns("/*");
registration.setName("CharacterEncodingFilter");
registration.setOrder(1);
return registration;
}
方案三:在application.yml指定編碼格式為utf-8
spring: http: encoding: charset: utf-8 enabled: true force: true server: tomcat: uri-encoding: UTF-8
方案四:寫個StringHttpMessageConverter

百度來的基本上都是長這樣。不過在spring5版本W(wǎng)ebMvcConfigurerAdapter這個類已經(jīng)過時。其替代方式是實現(xiàn)WebMvcConfigurer接口或者繼承WebMvcConfigurationSupport。不過如果使用WebMvcConfigurationSupport,則會使springboot的mvc自動裝配失效。失效的原因是

拓展一點小知識,加上@EnableWebMvc同樣也會springboot的mvc自動裝配失效。其原因是

org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration這個配置類繼承WebMvcConfigurationSupport

介紹那么多種方案,并沒有解決按例的問題。那問題點出在哪里?前邊案例我們提到過,在feign調(diào)用時,會把threadlocal的參數(shù)塞到header里面。真正亂碼的問題點就在這里,header是不支持中文傳輸?shù)模绻阌惨獋鬏?,基本上接收方接到就?#63;??這種看似亂碼的符號
破題關(guān)鍵
在把threadlocal的值塞到header里面時,先做下URLEncoder編碼,形如
URLEncoder.encode(“我是中文亂碼”,"UTF-8")
在接收header參數(shù)時,做下URLDecoder.解碼,形如下
URLDecoder.decode(header中待解碼的參數(shù)值, "UTF-8")
總結(jié)
方向錯了,雖然再怎么努力看似也啥沒卵用,不過至少可能會收獲其他意想不到的東西
以上就是springboot參數(shù)傳中文亂碼的解決方案的詳細內(nèi)容,更多關(guān)于springboot參數(shù)傳中文亂碼的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)之HashMap源碼深入分析
Java HashMap是一種基于哈希表實現(xiàn)的鍵值對存儲結(jié)構(gòu),可以實現(xiàn)快速的數(shù)據(jù)查找和存儲。它是線程不安全的,但在單線程環(huán)境中運行效率高,被廣泛應用于Java開發(fā)中2023-04-04
Springboot項目中如何讓非Spring管理的類獲得一個注入的Bean
這篇文章主要介紹了Springboot項目中如何讓非Spring管理的類獲得一個注入的Bean問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
SpringBoot打包成Docker鏡像的幾種實現(xiàn)方式
Spring Boot是一個用于構(gòu)建獨立的、可執(zhí)行的Spring應用程序的框架,結(jié)合使用Spring Boot和Docker,可以方便地將應用程序部署到不同的環(huán)境中本文,主要介紹了SpringBoot打包成Docker鏡像的幾種實現(xiàn)方式,感興趣的可以了解一下2024-01-01
SpringBoot Starter自定義之創(chuàng)建可復用的自動配置模塊方式
本文將詳細介紹如何設(shè)計和實現(xiàn)一個自定義的Spring Boot Starter,幫助讀者掌握這一強大技術(shù),提升代碼復用性和開發(fā)效率,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04
詳解Java的JDBC API的存儲過程與SQL轉(zhuǎn)義語法的使用
這篇文章主要介紹了詳解Java的JDBC API的存儲過程與SQL轉(zhuǎn)義語法的使用,JDBC是Java用于連接使用各種數(shù)據(jù)庫的API,需要的朋友可以參考下2015-12-12

