Java 解決中文亂碼問題

王如霜發表於2018-01-23

一:服務端解析客戶端

<% request.setCharacterEncoding("GB18030") %>

      在服務端解析客戶端的編碼設定(即伺服器接收瀏覽器傳送的資料),採用GB18030的方式,但是這樣有一點不好,如果我有1000個頁面(.jsp)需要設定需要重複寫這樣的語句1000條,重複工作,針對此問題的解決,下面給出瞭解決方案


二:客戶端解析服務端

<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%>

      客戶端解析服務端返回的資料的編碼方式(即瀏覽器呈現的頁面的編碼方式),如果一個.html 想改為.jsp,必須新增此句


三:Filter設定編碼

public class CharsetEncodingFilter implements Filter {
    private String encoding="";
    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
        //設定字符集,攔截request請求
        request.setCharacterEncoding(this.encoding);
        //繼續往下執行,這體現了職責鏈模式
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //初始化時,通過引數讀取filter的配置檔案的value值,即讀取設定的編碼方式
        this.encoding = filterConfig.getInitParameter("encoding");
    }
}

需要注意的幾點:

  • Filter是在tomcat啟動時new的,生命是由tomcat控制的
  • Filter只對Post請求起作用
  • Filter其實是對Request和Response請求進行了攔截
  • Filter可看作是一種橫切性的技術,面向切面的變成
  • Filter體現了“職責鏈模式”
  • 實現Filter需要實現javax.servlet.Filter介面,還要在web.xml檔案中進行配置
  • Filter提供了一種宣告式服務,宣告式服務非常強大,具有可插拔能力
    • 宣告式服務
      • 只需要宣告在哪裡where做什麼what,而不需關心如何實現how(體現為要在web.xml宣告對哪個檔案wher設定那種編碼what,具體怎麼實現寫在了filter類中)
    • 程式設計式服務
      • 需要以具體的程式碼表達在哪裡where做什麼what,如何實現how
        配置檔案web.xml設定如下:
<filter>
        <filter-name>CharsetEncodingFilter</filter-name>
        <filter-class>com.bjpowernode.drp.util.filter.CharsetEncodingFilter</filter-class> <!-- 具體的類路徑 -->  
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GBK</param-value>
            <!-- 體現了鍵值對,設定引數,在filter類中可根據encodign引數,取值GBK -->   
        </init-param>
    </filter>

    <filter-mapping>
        <!-- 對所有的.jsp起作用--> 
        <url-pattern>*.jsp</url-pattern>    
    </filter-mapping>

如果想對別的檔案也起作用:再添一個對映即可

    <filter-mapping>
        <filter-name>CharsetEncodingFilter</filter-name>
        <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

匹配檔案的一種寫法:

  • 精準匹配 寫完整的路徑
  • 擴充套件匹配,有星號*和副檔名組成,如*.jsp
  • 路徑字首匹配,包含一個目錄和一個/*,如/servlet/*,但不能寫/servlet/*.jsp
  • 全部匹配,一般使用/*
    執行過程:
    Java 解決中文亂碼問題
    這樣不用在每個.jsp中設定了,每次在請求服務端時,都會先走Filter,設定一下編碼

四:Get提交中文亂碼

      上面提到,Filter只對Post提交起作用,那麼當Get提交時,怎麼設定那,難道只能每個.jsp都要寫一遍嗎,當然不是,

  • Get提交可以考慮改變伺服器的配置,如Tomcat需要修改conf下的server.xml檔案,如:
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" 
               URIEncoding="GB18030"/>
  • 對中文采用java.net.URLEncoder.encode()進行編碼,如重定向時URL中有中文:
response.sendRedirect(request.getContextPath() + "/item_maint.jsp?errorMessage=" + URLEncoder.encode(errorMessage,"GB18030"));

相關文章