對於很多初學者來說,中文字符編碼不相同的問題,是一個很煩躁的問題!!
因為很多時候,我們並不知道,到底是哪一層出現了問題?
在這里稍微做個總結~也怕自己今后忘了!!
其實也就三層:
1、前端頁面
2、后台代碼
3、數據庫
記得考慮每一層之間的中文傳遞的問題,也就是前端傳到后台,還有后台傳到數據庫!!
詳解:
1、前端
前端就是設置頁面的字符集
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2、前端接受的數據傳入后台
一般我們是通過request.getParameter("XXX")方式獲取數據的,但是就算前端頁面字符集是正確的,也有可能在這一層出現問題。
因為傳遞中文的時候,有可能用A編碼拆解成Byte去傳遞,結果還原的時候使用B編碼還原,這就導致原來的數據出現亂碼或者???。。。等問題。
因此,我們可以通過String里面不同的構造方法來解決這個問題。(我們在第3部分,來修正這個問題)
3、后台代碼
這里分為兩塊講:
1)
先設置開發工具的編碼類型,一般來說是默認是gbk,但是這里我用utf-8,所以就得修改
有兩個地方要改:
a.Windows里面的Preferences(首選項框),在general里面找workspace,右側有text file encoding,改為utf-8(這個是開發ide的字符集修改)
b.鼠標點擊你的項目最頂層,然后在project里面找到這個項目的字符編碼,改為utf-8(項目的字符集修改)
2)
因為我如上所說的問題,所以代碼要在獲取數據之前指明request和response的編碼類型(我這里都用utf-8)
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
設置完成之后,可以這么獲取中文字符!
String name = new String(request.getParameter("name").getBytes("utf-8"), "utf-8"))
這里寫了兩個utf-8大家就會有點迷茫,其實是這個意思,第一個utf-8是說明從前端拿過來的byte是什么編碼格式的,第二個utf-8是指定把我的String字符串轉換成什么編碼格式。
一般來說使用new String(request.getParameter("name").getBytes(),"utf-8");就可以,盡量避免字符串的編碼轉來轉去,這樣會出現效率低下的問題,記得,先嘗試用最簡單的方式獲取,然后在后台打印下它的值,如果顯示正常,那么證明設置的沒有問題!
關於后台代碼,能改的差不多就這些
4、后台代碼通過jdbc寫sql將數據傳入數據庫(mysql為例)
這里還是有個比較惡心的地方,就是mysql如果你的字符集沒有設置,或者沒有設置好的話,默認是latin1
那么你的utf-8直接傳過來還是會出問題。
因此mysql的url要這樣寫:
//useUnicode表示允許使用自定義的Unicode,
//characterEncoding是給定自定義的Unicode是什么
String url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8"
我之前遇到中文在數據庫中顯示???(問號)的問題,就是因為沒有拼接上這兩個參數。因此mysql解析從后台代碼傳過去的字符串的時候,通過編碼類型去解析,所以就顯示不出正確的中文!
5、最后一步就是mysql字符集的設置
其實應該先分清楚有哪些字符集可以設置?
1)mysql的某個庫的字符集查看
可以通過use databasename;然后show variables like "%chara%"; 這個命令先查看下自己所使用的那個庫的字符集都是什么
character_set_client為客戶端編碼方式;
character_set_connection為建立連接使用的編碼方式;
character_set_database為數據庫的編碼方式;
character_set_results是結果集的編碼方式;
character_set_server為數據庫服務器的編碼方式。
只要保證以上采用的編碼方式一樣,就不會出現亂碼問題。
可以用如下的命令去修改:
set character_set_database="utf8"
以此類推,改成如上圖所示(或者符合自己的要求即可)。
然后可能會出現重啟完mysql修改的值就失效。可以在my.ini的文件中的[mysqld]標簽中設置:
default-character-set=utf8(但是這個是老版本的設置方式,具體什么版本,沒測過實在抱歉)
據說新版本是:character_set_server=utf8這個來代替之前的設置(大家可以自己嘗試下哪個生效)
設置完之后,mysql重啟下,應該字符編碼就沒問題了
2)mysql當中,用戶所使用的某個數據庫的字符集
這個就是創建數據庫的時候設置的字符編碼
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
utf8_general_ci是一種校對規則,有興趣可以自己研究下。
也可以在連接工具上直接編輯數據庫,來修改數據庫的字符集!
3)某個具體數據庫中的某張表的字符集
這個就是創建某張表的時候指定字符編碼
CREATE TABLE mytable(
id varchar(40) NOT NULL default '',
userId varchar(40) NOT NULL default ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
也可以在連接工具上直接改變表,來修改表的字符集!
其實就是把所有能改的地方全部改成utf-8(在數據庫中是utf8,沒有中間的 “ - ” ,千萬別加上去了)
提醒下,記得遇到報錯,要一層一層排錯!
1、首先是前端傳到后台的數據,在后台能正常打印嗎?
2、其次是后台傳輸到數據庫中的這個過程有沒有問題?
3、數據庫的字符編碼都是一樣的嗎?
像2和3這兩個方面,你可以拿一條帶中文的數據,直接在數據庫里面insert一條,如果插入進去,並且中文沒有異常,證明數據庫這邊是沒有問題的,那么就是傳輸時候的問題,很有可能是上述講的url沒有拼接那兩條參數。
這里,轉載一個大神的文章,我覺得這個說的很好:http://blog.csdn.net/cindy9902/article/details/6215769
以上,就是將大部分解決方法整理了下,如果全部設置了還不行,可以在下方留言,相互探討相互學習!謝謝~