springboot參數(shù)傳中文亂碼的解決方案
前言
本文案例來自業(yè)務(wù)部門的一個(gè)業(yè)務(wù)場(chǎng)景。他們的業(yè)務(wù)場(chǎng)景是他們部門研發(fā)了一個(gè)微服務(wù)上下文透?jìng)鹘M件,其透?jìng)髟硪餐?jiǎn)單的,就是通過springboot攔截器把請(qǐng)求參數(shù)塞進(jìn)threadlocal,然后下游通過threadlocal取到值,服務(wù)之間進(jìn)行feign調(diào)用時(shí),再把threadlocal的參數(shù)塞到header頭里面。這個(gè)組件一直用得好好的,突然有一天因?yàn)閭鞯膮?shù)值是中文,導(dǎo)致亂碼。他們通過嘗試下面的各種方案,都無法解決。最后就讓我們部門排查處理。
業(yè)務(wù)部門的實(shí)現(xiàn)思路
他們一開始的思路方向是參數(shù)編碼不一致導(dǎo)致中文亂碼。于是他們就朝這個(gè)方向努力著,于是就有了如下方案
方案一:
String value = new String("我是中文亂碼".getBytes("ISO-8859-1"),"UTF-8");
這個(gè)是常用解決字符串中文亂碼的方法之一
方案二:編寫字符編碼過濾器
@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() { } }
然后啟動(dòng)類上加上@ServletComponentScan。@WebFilter是servlet3.0才有的注解。當(dāng)然這個(gè)過濾器你還可以這么寫
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() { } }
然后啟動(dòng)類上加上@ServletComponentScan。@WebFilter是servlet3.0才有的注解。當(dāng)然這個(gè)過濾器你還可以這么寫
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() { } }
寫個(gè)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
方案四:寫個(gè)StringHttpMessageConverter
百度來的基本上都是長(zhǎng)這樣。不過在spring5版本W(wǎng)ebMvcConfigurerAdapter這個(gè)類已經(jīng)過時(shí)。其替代方式是實(shí)現(xiàn)WebMvcConfigurer接口或者繼承WebMvcConfigurationSupport。不過如果使用WebMvcConfigurationSupport,則會(huì)使springboot的mvc自動(dòng)裝配失效。失效的原因是
拓展一點(diǎn)小知識(shí),加上@EnableWebMvc同樣也會(huì)springboot的mvc自動(dòng)裝配失效。其原因是
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration這個(gè)配置類繼承WebMvcConfigurationSupport
介紹那么多種方案,并沒有解決按例的問題。那問題點(diǎn)出在哪里?前邊案例我們提到過,在feign調(diào)用時(shí),會(huì)把threadlocal的參數(shù)塞到header里面。真正亂碼的問題點(diǎn)就在這里,header是不支持中文傳輸?shù)?,如果你硬要傳輸,基本上接收方接到就?#63;??這種看似亂碼的符號(hào)
破題關(guān)鍵
在把threadlocal的值塞到header里面時(shí),先做下URLEncoder編碼,形如
URLEncoder.encode(“我是中文亂碼”,"UTF-8")
在接收header參數(shù)時(shí),做下URLDecoder.解碼,形如下
URLDecoder.decode(header中待解碼的參數(shù)值, "UTF-8")
總結(jié)
方向錯(cuò)了,雖然再怎么努力看似也啥沒卵用,不過至少可能會(huì)收獲其他意想不到的東西
以上就是springboot參數(shù)傳中文亂碼的解決方案的詳細(xì)內(nèi)容,更多關(guān)于springboot參數(shù)傳中文亂碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于Java中進(jìn)制的轉(zhuǎn)換函數(shù)詳解
下面小編就為大家?guī)硪黄贘ava中進(jìn)制的轉(zhuǎn)換函數(shù)詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07Spring中property-placeholder的使用與解析詳解
本篇文章主要介紹了Spring中property-placeholder的使用與解析詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05IDEA2020.3創(chuàng)建web工程的完整步驟
這篇文章主要給大家介紹了關(guān)于IDEA2020.3創(chuàng)建web工程的完整步驟,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Spring深入分析講解BeanUtils的實(shí)現(xiàn)
java知識(shí)體系統(tǒng)有很多數(shù)據(jù)實(shí)體,比較常用的DTO、BO、DO、VO等,其他類似POJO概念太老了現(xiàn)在基本廢棄掉了,本篇幅直接忽略,對(duì)于這幾種數(shù)據(jù)實(shí)體各自代表的含義和應(yīng)用場(chǎng)景先做一下簡(jiǎn)單描述和分析2022-06-06SpringBoot如何根據(jù)目錄路徑生成接口的url路徑
這篇文章主要介紹了SpringBoot如何根據(jù)目錄路徑生成接口的url路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11Java?SimpleDateFormat與System類使用示例詳解
這篇文章主要介紹了Java?SimpleDateFormat與System類使用示例,對(duì)于SimpleDateFormat類,是一個(gè)用來區(qū)分區(qū)域設(shè)置的方式進(jìn)行日期的是指,以及對(duì)日期進(jìn)行處理分析的一個(gè)實(shí)現(xiàn)類2022-11-11