中文亂碼解決辦法

一、實際項目遇到的問題

客戶端發送POST請求訪問接口, 請求參數放在Body當中。每一個參數utf-8編碼,從獲取出來的中文參數時亂碼 請求截圖: java

image.png
服務器端獲取company參數:request.getParameter("company") 爲 」我去饿我去「。亂碼!!

2.一、中文亂碼的根本緣由:

Servlet3.0規範中有關請求參數編碼的解釋以下: 當前不少瀏覽器並不發送帶Content-Type頭部的字符編碼標識符,它會把字符編碼的決定留在讀取HTTP請求的時候。若是客戶端沒有指明編碼,容器用來建立請求讀和解析POST數據的默認編碼必須是"ISO-8859-1"。然而,爲了提示開發者客戶端沒有成功發送一個字符編碼,容器中getCharacterEncoding方法會返回null。 若是客戶端沒有設置字符編碼,而且請求數據使用了不一樣編碼而不是上述的默認編碼,程序將會出現中斷。爲了糾正這種狀態,一個新的方法setCharacterEncoding(String enc) 被添加到ServletRequest接口。開發者調用這個方法能重寫容器提供的字符編碼。這個方法必須在解析request中任何post數據或者讀任何輸入以前調用。一旦數據已經被讀取,調用這個方法不會影響它的編碼。web

2.二、另一種理解:

setCharacterEncoding("utf-8"); 該函數是用來設置HTTP請求或者相應的編碼格式 對於HttpServletRequest,是指提交參數的編碼,指定後能夠經過getParameter()方法直接獲取到正確的字符串。若是不指定則默認使用is08859-1編碼。參見下述「表單輸入「。須要注意的是在執行setCharacterEncoding()以前 ,不能執行任何getParameter()獲取參數。java doc上寫明:This method must be called prior to reading request parameters or reading input using getReader()。並且該指定只對POST方法有效。對GET方法無效。分析緣由:應該是在執行第一個getParameter()的時候。JAVA將會按照編碼分析全部的提交參數,然後續的getParameter()將再也不分析編碼。因此setCharacterEncoding()無效。而對於GET方法請求時。請求的參數在URL上,一開始就已經按照編碼分析全部的參數,setCharacterEncoding()天然就無效。 對於response, 則制定輸出內容的編碼, 同時改設置會傳遞給瀏覽器, 通知瀏覽器輸出的內容所採用的編碼。spring

3.一、解決方法:web.xml中配置編碼Filter

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
複製代碼
注意:

一、web.xml中,這段配置要放在全部filter的最前面,不然會不生效,根本緣由請見上述第三點的解釋 二、兩個初始化參數的做用,其實看這個Filter的源碼就一目瞭然,這兩個參數是用來決定是否要設置request和response中的編碼。源碼很簡潔:瀏覽器

public class CharacterEncodingFilter extends OncePerRequestFilter {    
     private String encoding;    
     private boolean forceEncoding = false;    
     public CharacterEncodingFilter() { }    
     public void setEncoding(String encoding) {        
         this.encoding = encoding;    
     }    
     public void setForceEncoding(boolean forceEncoding) {        
         this.forceEncoding = forceEncoding;    
     }    
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {        
         if(this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {            
             request.setCharacterEncoding(this.encoding);            
             if(this.forceEncoding) {                
                 response.setCharacterEncoding(this.encoding);            
             }        
          }        
          filterChain.doFilter(request, response);    
     }
 }
複製代碼

3.二、解決方法:設置Content-Type

若是post請求方式是x-www-form-urlencoded,那麼設置以下: Content-Type=application/x-www-form-urlencoded;charset=utf-8 這樣經過request對象取body體裏面的中文是正常的。 這種方式有一點須要注意: 若是請求方式是multipart/form-data,如上設置會致使request取不到參數。Content-Type要與傳遞數據匹配(本文data)bash

3.三、手動編解碼

例如參數爲company服務器

String company= new String(request.getParameter("company").getBytes("iso-8859-1"), "utf-8");
複製代碼
相關文章
相關標籤/搜索