1. 程式人生 > >解決Java中Web開發的中文亂碼問題

解決Java中Web開發的中文亂碼問題

      對於大多數從事Java開發的程式設計師來說,Java中的中文亂碼是個很頭痛的問題。在Web開發中尤為凸顯,明明在頁面中輸入的是中文,為什麼在資料庫中儲存的卻是不是中文,而是我們看不懂的文字。用程式中專業的術語來說,是亂碼,不是我們所想要的結果。那麼這個問題應該怎麼來解決呢?

      在做HTML頁面時,為了統一頁面中不會出現中文亂碼問題,我們就把在<head></head>標籤中<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />的charset改為GBK或者是gb2312。這是在HTML中的應用,我當時記得授課老師只是提了一下,說要把charset改為GBK或者gb2312即可,這是一箇中文的編碼格式。當然,可能在這裡談HTML與Java好像沒有關係,不過在Java中,解決中文亂碼問題也是把字元編碼格式改為GBK或者gb2312即可。不過,一般都改為GBK,改為gb2312的很少,我也沒有用過,但是效果卻是一樣的。

      在Java中,有一個過濾器的概念。Java的類庫中,Java的開發者已經寫好了這個介面。我們只需要去實現這個介面,把介面中的方法寫好即可。現在,就用過濾器來解決中文的亂碼問題。

      首先,在Java的Web工程下建一個包,我在此把名字取為com.aptech.jb.epet.filter。在這個包裡面建一個普通的Java類,這個類要實現一個javax.servlet.Filter包下的Filter介面。裡面有3個方法,分別是destroy()、doFilter()和init()。其中先不管其中的destroy()和init()方法,先看doFilter()方法。在這三個方法中,除了第一個方法沒有引數外,其它兩個方法都是有參的。

如圖所示:

      

      其中,doFilter()方法中,ServletRequest、ServletResponse、FilterChain中原來的引數名不是request、response和chain,只是我們把引數名改了而已。ServletRequest、ServletResponse、FilterChain只是引數型別,把前面兩個引數名改為request、response是因為這兩個是JSP中的內建物件。在JSP開發中經常使用。然後在方法體中寫兩名句程式碼即可解決中文亂碼問題,如圖中所示。當然,在其中也會有IO和Servlet異常,我們只需用throws關鍵字要把它丟擲即可。

      在寫好了這個過濾器類後,也不就萬事大吉了。重新部署執行後亂碼還是沒有解決,是什麼原因呢?寫好這個類後,不要忘了,還要在Web專案中web.xml檔案中配置,這樣過濾器才真正實現瞭解決亂碼的功能。

      在web.xml中配置如圖所示:

     

       在這裡,有幾點要說明一下。在<filter></filter>節點下的<filter-name></filter-name>節點中,這裡要給過濾器取個名字,這個名字可以隨心所欲的取,不過也要注意命名的規範,在上一章中我已經談到了關於命名規範的問題;<filter-class></filter-class>節點中,這裡要指定過濾器所在的位置,也就是剛才我們定義的那個地方。不過此時要特別注意,路徑中一定要包名+類名。如果不是,那麼在執行時系統找不到過濾器類,過濾器也不會起作用。而後在<filter-mappin></filter-mappin>節點下的<filter-name></filter-name>節點中,這個名字一定要和前面<filter></filter>節點下的<filter-name></filter-name>節點所取的名字一定要相同。如果不同,過濾器也不會起作用。最後是訪問路徑的問題,在<url-patten></url-patten>節點中配置為/*,表示以每一次請求都會被這個過濾器所攔截。若是字元,則轉換為中文。這樣,Web開發中Java的中文問題就解決了,在執行系統時就不會出現亂碼了。

      前面提到的destroy()和init()方法,我也沒有太多的研究,暫時也不知道它有什麼作用,只管doFilter()方法配好即可。

      在學習Servlet技術時,也學習了一下解決中文亂碼問題的方法。即是在Servlet的doPost()或者doGet()方法中,增加一句request.setCharacterEncoding("GBK"); 的程式碼即可。不過,個人認為這種方法不可取,在稍有點規模的專案中,有很多Servlet,只要有新增功能的Servlet,就要寫這句程式碼,那麼意味著要寫很多重複的程式碼,這也違反了Java的開閉原則。在此時,建議使用過濾器,這樣需寫一次程式碼就解決了亂碼問題。對比一下,你會選擇哪一種呢???