POST和GET方法亂碼解決方案

前言

在WEB開發的過程中,中文亂碼是最爲常見的問題之一。之所以會出現中文亂碼的情況,主要原因是:前端使用POST或者GET方法傳遞的參數一般使用瀏覽器預先設置的編碼方式進行編碼,中文瀏覽器一般是使用UTF8或者GBK,英文的一般是ISO編碼;而瀏覽器編碼完成後發送給服務器,服務器進行解碼的解碼方式默認是使用ISO8859-1。這就造成了編碼和解碼方式不統一的,進而出現了中文亂碼的問題。

在下面,我將給出分別對POST、GET方法亂碼的解決方案

對POST方法和GET方法的簡介

POST方法和GET方法是前端將表單中的內容提交到服務器端的方法,二者有着很大的不同之處。
首先,GET方法是直接把表單中的內容直接放在了URL中進行傳值,就像這種:
image
可以很明顯的看到,使用這種方式進行傳參是對用戶可見的,這就有了一定的安全隱患,所以,一般這種方法都不會用在對安全性有要求的地方。
其次,POST方法就相對安很多了,POST方法會將參數放入HTTP請求報文的實體部分,對用戶來講是不可見的。
對於HTTP的介紹,我今後會寫一篇詳細的博客來爲大家講解,細數HTTP協議的相關內容,敬請期待。

解決方案

POST方法

對於POST方法,解決起來相對簡單。只需要在讀取參數之前設置一下解碼的的格式就行了。代碼示例如下:

public class LoginServlet extends HttpServlet{
    public void service(HttpServletRequest request,HttpServletResponse response){
        //將解碼格式設置成UTF8
        request.setCharacterEncoding("utf8");
        String username = request.getParameter("username");
    }
}

GET方法

而對於GET方法,就是比較麻煩的了。
第一種方案是,拿到所有的從前端傳遞過來的參數,進行統一編碼,然後是用正則表達式,字符串的split函數split(“&”)進行切割,切割完成後,再分別取出參數值。

//取出所有的參數
String allParameters = request.getQueryString();
//對參數重新編碼
String parameters = java.net.URLDecoder.decode(allParameters,"UTF-8");
//正則分割
String[] parameter = parameters.split("&");

第二種方案就更麻煩了。
首先要做的是獲取到請求的參數值,然後對這個參數值使用ISO-8859-1的格式分解成字節數組,然後再重新生成爲一個編碼格式是UTF8的字符串。

//獲取參數值
String name = request.getParameter("name");
//把參數值變成字節數組
byte[] nameBytes = name.getBytes("ISO-8859-1");
//生成新的編碼爲UTF8的字符串
String newName = new String(nameBytes,"UTF-8");

使用過濾器Filter

很明顯,如果我的服務端有着大量的Servlet,這樣的做法會造成大量的代碼重複,顯然是不滿足代碼複用的要求的,於是我們選擇使用過濾器,對請求進行過濾。
下面的這個文件是對兩種請求方式的編碼與解碼。
EncodingRequest.java

public class EncodingRequest extends HttpServletRequestWrapper {  
    private String charset;  
    public EncodingRequest(HttpServletRequest request, String charset) {  
        super(request);  
        this.charset = charset;  
    }  

    public String getParameter(String name) {  
        HttpServletRequest request = (HttpServletRequest) getRequest();  

        String method = request.getMethod();  
        if(method.equalsIgnoreCase("post")) {  
            try {  
                request.setCharacterEncoding(charset);  
            } catch (UnsupportedEncodingException e) {}  
        } else if(method.equalsIgnoreCase("get")) {  
            String value = request.getParameter(name);  
            try {  
                value = new String(name.getBytes("ISO-8859-1"), charset);  
            } catch (UnsupportedEncodingException e) {  
            }  
            return value;  
        }  
        return request.getParameter(name);  
    }  
}  

這個文件是過濾器,將所有請求都進行過濾。

public class EncodingFilter extends HttpFilter {  
    public void doFilter(HttpServletRequest request,  
            HttpServletResponse response, FilterChain chain)  
            throws IOException, ServletException {  
        String charset = this.getInitParameter("charset");  
        if(charset == null || charset.isEmpty()) {  
            charset = "UTF-8";  
        }  
        response.setCharacterEncoding(charset);  
        response.setContentType("text/html;charset=" + charset);  
        EncodingRequest res = new EncodingRequest(request, charset);  
        chain.doFilter(res, response);  
    }  
}  

最後,爲了讓過濾器工作,配置一下web.xml文件

<filter>  
    <filter-name>EncodingFilter</filter-name>  
    <!--包名及文件名-->
    <filter-class>cn.roobtyan.filter.EncodingFilter</filter-class>  
    <init-param>  
        <param-name>charset</param-name>  
        <param-value>UTF-8</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>EncodingFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>  

做完如上工作,亂碼就解決了。

結語

感謝您的閱讀,歡迎指正博客中存在的問題,也可以跟我聯繫,一起進步,一起交流!

微信公衆號:進擊的程序狗
郵箱:[email protected]
個人博客:http://roobtyan.cn
掃描下面的二維碼關注我吧,你將收穫到意想不到的東西喲……
給大家準備了一份非常棒的JAVA的視頻教程,從JAVA基礎一直到JAVAWEB,還有非常強大的項目實戰。
就在我的微信公衆號裏,回覆java就可查看,免費的呦!
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章