昨天在整合Spring MVC和Velocity,Sitemesh時,又碰到了久違的中文問題。唉,JSP, mysql, struts,每次都會碰到這樣的問題,總是以為這種以后不會碰到這種看似初級的問題了,結(jié)果還是躲不過。網(wǎng)上沒查到相關(guān)資料,于是開始動手跟蹤Spring和Velocity的源碼,弄了一天終于搞定。后來一個同學告訴我這個問題在Spring中文論壇里有精華貼,跟我最后的解決方案一樣的,氣死我也。不過跟蹤Spring的源代碼收獲還是不錯的,現(xiàn)在又對Spring的MVC framework有了更深的認識。這里把以前碰到的中文問題大概列一下,方便以后參考。
1、JSP頁面顯示的中文問題
這是最初級的東西,網(wǎng)上到處都有,不過還是列一下吧:
Page的第一行改成:<%@ page contentType="text/html; charset=gb2312" %>
Head里加:
2、頁面Form 內(nèi)容提交的中文問題
在web.xml里加入:
CharacterEncodingFilter
Character Encoding Filter
no description
org.springframework.web.filter.CharacterEncodingFilter
encoding
GB2312
forceEncoding
true
CharacterEncodingFilter
/*
呵呵,這是個簡單得要命的filter,如果不用Spring的話,完全可以自己寫一個。其實任何的interceptor機制都可以處理這個的,不管用Webwork還是Spring的interceptor,甚至用AOP,只要在取參數(shù)前加那么一句:request.setCharacterEncoding("GB2312");就行了。以前我用struts就是在它的RequestProcessor的populate之前加了這么一行。
3、request 的parameter里要傳中文參數(shù)的問題
這個問題跟Web Container有關(guān)系,記得以前我同學用WebLogic時好象沒出現(xiàn)這樣的問題。(我一般不傳中文參數(shù),呵呵)。
Tomcat里的解決方案是在server.xml里Connector port="8080"的attribute里加URIEncoding="GB2312"
當然還有最土的解決方案,雖然不太會用到,不過還是列出來,以備最無奈的時候使用:
String encodeStr=new String(fieldValue.getBytes("8859_1"), "gb2312");
4、mysql的中文問題
首先要修改mysql配置文件的encoding為GB2312,這部分的操作不記得了,畢竟好久沒用mysql了。不過據(jù)說新版的mysql里有wizard可以設(shè)的。然后把jdbc connection改成如下:
jdbc:mysql://localhost:3306/bsfbookstore?useUnicode=true;characterEncoding=GB2312
另外在寫程序成盡量用PrepareStatement,少用Statement,好象jdbc驅(qū)動在解析statement里的SQL包含中文時會有問題。(用PrepareStatement也是好習慣, hibernate里全用PrepareStatement的,哈哈)
5、Spring與Veclocity結(jié)合的中文問題
第一步:
在"velocityConfig"里配置velocity.propeties文件,加下面一行:
/WEB-INF/velocity.properties
呵呵,也可以在config里直接用Map把參數(shù)寫進去,這樣就不用properties文件,這個Spring的文檔里都有。
然后在velocity.properties里寫:
input.encoding=GB2312
output.encoding=GB2312
default.contentType=text/html; charset=GB2312(ms這一行沒有用處,Spring有個地方讀進這個參數(shù),不過后來又覆蓋掉了)
第二步:
接下來就是我昨天調(diào)了半天的那個地方,最后的解決方案很簡單,在viewResolver配置里加一行:
text/html; charset=GB2312
呵呵,就這么一行害我debug了好久,跟蹤了Velocity的Context設(shè)置,甚至改了Spring的源碼,用了Filter,Spring的Handler interceptor來設(shè)置reponse的contentType就是沒效果,結(jié)果發(fā)現(xiàn)Spring在Velocity View的render里加了這么一行:
response.setContentType(getContentType());
呵呵,原先設(shè)好的contentType都被沖掉了,因為render的時機是在postHandler之后,呵呵。
這個參數(shù)對jsp是沒有用的,因為jsp會根據(jù)自己頁面的contentType設(shè)定的,所以每個JSP必須設(shè)置自己的contentType,Velocity就不用啦。難怪以前用JSP的時候沒碰到這個問題。