JSF/Facelets默認使用UTF-8來解碼HTTP請求參數。 GlassFish默認使用ISO-8859-1來解碼HTTP請求參數。 HTTP請求參數只能被解析和解碼一次,並且只要代碼首次請求請求參數,就會發生這種情況,如request.getParameter("name")
。因此,如果第一次請求參數之前JSF已經將請求參數編碼設置爲UTF-8,那麼它將(使用ISO-8859-1進行錯誤地解析)。
當JSF需要設置請求參數編碼期間恢復視圖階段如下,
request.setCharacterEncoding("UTF-8");
而請求參數已被解析,然後將GlassFish的準確顯示該警告。
不必要的後果是,所有這些HTTP請求參數可能最終在Mojibake。表單數據最初是使用UTF-8提交和編碼的。如果使用ISO-8859-1等不同的字符集對UTF-8數據進行解碼,則8位及以上的字符(通常是「特殊字符」,如é
,à
,ö
等)將被破壞和在é
結束,Ã
,ö
等
技術上,正確的解決方案是不請求 HTTP請求參數之前 JSF設定了正確的編碼。你基本上需要檢查所有的碼在JSF的恢復視圖階段之前運行,如servlet過濾器,階段監聽器等,如果他們沒有這樣做。
如果您似乎無法找到它,或者代碼無法控制,那麼您可以告訴GlassFish使用UTF-8來解碼HTTP請求參數,以便在JSF需要時不需要更改它得到它們。你可以通過添加以下條目添加到您的/WEB-INF/glassfish-web.xml
文件的<glassfish-web-app>
:
<parameter-encoding default-charset="UTF-8"/>
(注:文件和根條目以前稱爲sun-web.xml
和<sun-web-app>
分別)
注意到應該是這是GlassFish特有的,當你將webapp部署到不同的服務器時,這一切都不起作用。規範獨立於服務器的方法是創建一個servlet filter基本上做以下工作在doFilter()
方法:
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
,並確保它被一個需要收取任何HTTP請求參數的任何其它過濾器之前映射。
更新:爲何GlassFish中已經預先設置它,它可能是由PrimeFaces引起的。另請參閱此相關問題:Unicode input retrieved via PrimeFaces input components become corrupted。
從我的經驗,這名消息丟失。你在使用哪一個? – Osw
@Osw:在最早的Mojarra 2.0.x版本中確實存在一個相關的錯誤,但這是由一個稍微不同的問題引起的,並且隻影響了Ajax請求。然而OP使用捆綁JSF 2.1的GF 3.1。 – BalusC
@osw:特別是我正在使用GF 3.1.1 Build 12.我可能不應該,但我讓Netbeans和GF儘快下載所有更新。但是,我幾乎在每個版本級別都記得這個問題。它只是到了我測試了很多頁面的地步,在這個過程中產生了足夠多的這些錯誤信息,我被激勵採取行動。順便說一下,這個包中的Mojarra版本是2.1.3(FCS b02)。 – AlanObject