1.重現問題前端
在web項目中有時會用到pager-taglib來做爲分頁的標籤,如上圖紅色框標識所示,當咱們須要把頁面參數保持的時候咱們會在<pg:param />標籤中把參數進行傳遞。java
若是你的頁面編碼爲gb2312那這樣寫是沒有問題的,可是若是你的頁面編碼是utf-8的話那就會出現亂碼問題。我嘗試了不少方法,編碼過濾器,編碼攔截器(struts2),傳遞 web
參數的時候進行編碼而後後臺進行解碼,還有WEB(如TomCat等)應用服務器編碼。仍是以爲這些方法沒有從根本上解決問題。既然是用pager-taglib標籤進行分頁,那咱們就服務器
去看看pager-taglib裏面關於字符集編碼的處理。eclipse
2.pager-taglib字符集處理源碼工具
a.首先咱們要準備一個pager-taglib-2.0的war包編碼
b.而後咱們把它解壓操作系統
在WEB-INF下面的lib包下面有兩個jar包.net
c.pager-src.jar這就是pager-taglib的源碼包,咱們打開它找到final void addParams(String name, Stringvalue)這個方法翻譯
上圖標紅的幾行代碼很容易就能看出URLEncoder.encode(value)方法就是在對傳遞的參數進行字符集編碼處理,那具體是怎麼處理呢?
咱們繼續跟進去看源碼.
d.URLEncoder源碼
找到這個方法後咱們發現它已經被標上了@Deprecated的註解,這是個什麼意思,因爲英文很差,咱打開翻譯工具查一下
好吧,已是不推薦的方法了,可是不要緊,這個方法它調用了另一個encode(s, dfltEncName)方法,那咱繼續跟進去看
一大段源碼,看關鍵地方
if(enc == null){
throw new NullPointerException("charsetName");
}
我不是技術大牛,可是一看到charstName這個關鍵字,咱仍是知道確定跟字符集有關,那enc這個參數是什麼意思呢?
往上看,這個就是那個過期的encode(s, dfltEncname)傳遞過來的參數dfltEncName不就是是defaultEncName的縮寫?
什麼意思呢?默認的環境名稱?不清楚繼續找看哪裏有對這個變量的操做:
而後在這個類的staic靜態塊裏面找到了
到此咱仍是不明白究竟是個怎麼處理過程,不要急,繼續找這個GetPropertyAction("file.encoding")的麻煩,可是看到這個方法是否是很眼熟?
咱要得到咱當前操做系統的字符集編碼不是都這麼寫嗎?
而後咱再進GetPropertyAction這個類的源碼看看
好吧,看到這裏想必你們都明白了,原來pager-taglib默認最字符集編碼的處理就是使用你當前操做系統的編碼方式,
就算你頁面設置的其餘的字符集編碼,它也不會管你的,它仍是取得當前系統的字符集編碼方式而後處理,忽然以爲
編寫這個pager-taglib的人好JB蠢。 通常若是咱使用的是window的操做系統,那麼編碼都是GBK,到此咱就明白了吧。
由於你的頁面用的是utf-8編碼,而你傳遞中文參數的時候pager-taglib又默認用GBK編碼進行的處理,理所固然就會出現亂碼了。
那麼解決方案呢?
咱再回到PagerTag類裏面,就在encode()方法下面一點,咱仔細一看有這麼一行代碼
String[] values = pageContext.getRequest().getParameterValues(name);
這不是牛B的pageContext對象嗎?那咱是否是能夠從這個上下文中拿到頁面你設置的編碼方式呢?
答案是確定的,因此咱只需作以下修改
\
3.解決問題
好了,接下來須要作的事很簡單了,將你修改事後的東西整個打成jar包而後上傳的項目就能夠解決中文亂碼問題了,你不再用encode()過去,decode()回來了.
a.首先在你的IDE中新建一個名爲pager-taglib的項目,而後把官方的pager-src下面的com包下面的java類和META-IF導入
找到PagerTag.java類進行上面解決方案中的修改,而後用你用的IDE導出jar包,我用的是myeclipse
File --> Export -->java --> JAR file
4.總結
剛遇到這個問題的時候我也去網上找解決辦法。關於最後進行修改編碼的這部分,網上有相關的文章,可是幾乎全部的都只是說pager-talib用的是你係統
默認的編碼方式,須要改爲你頁面的編碼方式。可是我的不喜歡這種知其然不知其因此然的方式,因此本身跟着源碼進去找到了pager-taglib究竟是怎麼用
系統默認的編碼方式的,最後想要取得頁面編碼方式的時候又看到了pageContext這個對象,又加強了本身對pageContext這個對象的認識。由於網上有很
多修改編碼方式是直接寫上去的就像這樣
name = java.net.URLEncoder.encode(name, "utf-8");
value = java.net.URLEncoder.encode(value, "utf-8");
我的以爲這是很愚蠢的辦法,由於致使中文亂碼的緣由並非你沒有使用utf-8的編碼,而是由於頁面和pager-taglib處理中文亂碼的編碼不一致致使的,
雖然如今基本上對中文編碼的處理就utf-8和gbk可是我假若有不少對於中文編碼的處理,當我頁面用的另一種其餘的編碼的時候你仍是在這裏寫死utf-8
豈不是很2B?因此這裏仍是推薦
name = java.net.URLEncoder.encode(name, pageContext.getResponse().getCharacterEncoding());
value = java.net.URLEncoder.encode(values[i], pageContext.getResponse().getCharacterEncoding());
這種方式,由於咱們須要作的只是取到頁面的編碼方式和pager-taglib保持一致而已.
固然,可能還有一些其它的更好的解決方案,或者其它的問題所致使的亂碼問題,這裏僅推薦我的以爲適合的對這個問題的解決方案.