JSF/Facelets 默认使用 UTF-8 来解码 HTTP 请求参数。 GlassFish 本身默认使用 ISO-8859-1 来解码 HTTP 请求参数。 HTTP 请求参数只能解析和解码一次,每当代码第一次请求请求参数时就会发生这种情况,如下所示request.getParameter("name")
。所以,如果第一次请求某个请求参数beforeJSF 已将请求参数编码设置为 UTF-8,那么它将(错误地)使用 ISO-8859-1 进行解析。
当JSF需要在恢复视图阶段设置请求参数编码时,如下所示:
request.setCharacterEncoding("UTF-8");
当请求参数已经解析时,GlassFish 将准确显示此警告。
不想要的结果是,所有这些 HTTP 请求参数可能最终会出现在Mojibake。表单数据最初是使用 UTF-8 提交和编码的。如果您使用不同的字符集(例如 ISO-8859-1)解码 UTF-8 数据,则 8 位范围及以上的字符(通常是那些“特殊字符”,例如é
, à
, ö
等将被损坏并最终出现在é
, Ã
, ö
, etc.
从技术上讲,正确的解决方案是not请求HTTP请求参数beforeJSF 已设置正确的编码。您基本上需要检查在 JSF 恢复视图阶段之前运行的所有代码,例如 servlet 过滤器、阶段侦听器等(如果它们没有这样做)。
如果你似乎找不到它,或者代码超出了你的控制范围,那么你可以告诉 GlassFish 使用 UTF-8 来解码 HTTP 请求参数,这样当 JSF 想要获取时不需要更改它他们。您可以通过将以下条目添加到<glassfish-web-app>
你的/WEB-INF/glassfish-web.xml
file:
<parameter-encoding default-charset="UTF-8"/>
(注意:文件和根条目之前称为sun-web.xml
and <sun-web-app>
分别)
应该注意的是,这是特定于 GlassFish 的,当您将 Web 应用程序部署到不同的服务器时,这一切都不起作用。规范的独立于服务器的方法是创建一个小服务程序过滤器它基本上做了以下工作doFilter()
method:
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
并确保它在需要收集任何 HTTP 请求参数的任何其他过滤器之前进行映射。
Update:至于为什么GlassFish会预先设置它,可能是PrimeFaces造成的。另请参阅此相关问题:通过 PrimeFaces 输入组件检索的 Unicode 输入已损坏.