22

这是在 GlassFish 3.1 上,在 Mojarra 上使用 PrimeFaces 并用 MyFaces CODI 加盐。几乎每个请求都会出现以下消息:

WARNING: PWC4011: Unable to set request character encoding to UTF-8 from context /com.myapp_war_0.1,因为请求参数已经被读取,或者 ServletRequest.getReader() 已经被调用

自从我开始这个项目以来就发生了这种情况——到目前为止我一直忽略它,但现在我意识到我在浪费大量时间阅读它。我在这里找到了一个有趣但不完整的解决方法,但我不明白。

有人可以建议如何在不抑制其他可能警告消息的情况下删除此消息吗?

4

1 回答 1

41

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 位及以上范围内的字符(通常是那些“特殊字符”,如éàö等)将被损坏并最终在é, à,ö

从技术上讲,正确的解决方案是在JSF 设置正确的编码之前请求 HTTP 请求参数。您基本上需要检查在 JSF 的恢复视图阶段之前运行的所有代码,例如 servlet 过滤器、阶段侦听器等,如果它们没有这样做的话。

如果您似乎找不到它,或者代码超出您的控制范围,那么您可以告诉 GlassFish 使用 UTF-8 来解码 HTTP 请求参数,这样 JSF 想要获取时就不需要更改它他们。您可以通过将以下条目添加到文件<glassfish-web-app>中来做到这一点/WEB-INF/glassfish-web.xml

<parameter-encoding default-charset="UTF-8"/>

sun-web.xml(注意:文件和根条目之前<sun-web-app>分别被调用过)

应该注意的是,这是 GlassFish 特有的,当您将 web 应用程序部署到不同的服务器时,这一切都不起作用。规范的独立于服务器的方法是创建一个servlet 过滤器,它在方法中基本上完成以下工作doFilter()

request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);

并确保它在需要收集任何 HTTP 请求参数的任何其他过滤器之前被映射。


更新:至于GlassFish为什么提前设置,可能是PrimeFaces造成的。另请参阅此相关问题:通过 PrimeFaces 输入组件检索的 Unicode 输入变得损坏

于 2011-10-04T12:32:40.503 回答