2009年1月29日

解決JSF的outputLink中文網址編碼問題

h:outputLink是JSF(JavaServer Faces)的HTML Tags,作用如同HTML的<a href="..."></a>標籤,它的作用是搭配JSP的EL(Expression Language),可以讓JSP在產生連結的部份,不用摻雜Java字串相加及URL編碼的處理,使得JSP的代碼採用一致、比較容易維護(?)的XML。

關於JSF的h:outputLink使用方法教學,首推良葛格的筆記「JSF Gossip: 輸出類標籤」這篇。

這篇文章要談論的問題,是網址中必須包含「中文」時的處理。

h:outputLink的value屬性值,就是超連結的位址,如果使用英數字不會有問題。

<h:outputLink value="english.jsp" />

但是若有包含中文(或其他Unicode、非英數字及符號的字元),就會造成編碼錯誤。

<h:outputLink value="中文檔名.doc" />

最好的情況,當然是避免直接用中文檔名,因為位址中的中文,對於瀏覽器及伺服器會如何作處理,開發者比較難掌握。

程式檔案(例如.jsp)的命名,當然容易避開中文。但是很常見的一種情況是,必須提供中文命名的檔案給使用者下載,可以用以下的方法解決。

設計一個redirect程式,例如redirect.jsp,接收一個名稱為url的參數,並藉由sendRedirect(或http header的Location:)重新導向這個指定的url參數值;或是在程式中把檔案的二進位內容讀出來,搭配適當的http header傳回給瀏覽器。只要有這個redirect.jsp可以正確處理參數指定的檔案,h:outputLink就可以改寫如下。

<h:outputLink value="redirect.jsp">
<f:param name="url" value="中文檔名.doc" />
</h:outputLink>


產生的<a>標籤,href屬性的連結就是「redirect.jsp?url=中文檔名.doc」這種形式,其中url算是GET參數,所以會被編碼,但redirect.jsp接收到(getParameter)的參數值,將會是正確的中文檔名。

另一種是比較投機取巧的方法,不必再多寫一支程式處理,而是直接避開h:outputLink中value會被編碼的問題,但如果瀏覽器或伺服器,沒辦法處理中文檔名,那仍會有連結不到的問題。

<h:outputLink value="#" onclick="this.href='中文檔名.doc';" />

這個方法藉由onclick事件,在連結被點下的時候,即時將href設定的位址修改。

強迫使用者必須要開啟JavaScript才能點擊連結,實在不是一個好的設計,但這個方法用在暫時patch現有的系統,相當快速好用。例如Sakai的許多Tools的程式碼,搭配JSF就使用h:outputLink,造成對Resources中有中文檔名的連結無法存取,就是個適用這種快速解法的案例。

沒有留言:

張貼留言

lyhcode by lyhcode
歡迎轉載,請務必註明出處!