如何摆脱警告:PWC4011:无法将请求字符编码设置为 UTF-8
这是在 GlassFish 3.1 上,使用 PrimeFaces over Mojarra 并使用 MyFaces CODI 进行加盐。几乎每个请求都会出现以下消息:
警告:PWC4011:无法从上下文 /com.myapp_war_0.1 将请求字符编码设置为 UTF-8,因为请求参数已被读取,或者 ServletRequest.getReader() 已被调用
自从我启动项目以来,就发生了这种情况——到目前为止我一直忽略它,但现在我意识到我浪费了很多时间阅读它。我在此处找到了一个有趣但不完整的解决方法,但我不明白它。
有人可以建议如何在不抑制其他可能的警告消息的情况下压制此消息吗?
This is on GlassFish 3.1, using PrimeFaces over Mojarra and salted with MyFaces CODI. On just about every request the following message appears:
WARNING: PWC4011: Unable to set request character encoding to UTF-8 from context /com.myapp_war_0.1, because request parameters have already been read, or ServletRequest.getReader() has already been called
This has happened ever since I started the project -- so far I have been ignoring it but now I have realized I am wasting a lot of time reading around it. I found an interesting but incomplete work-around here, but I don't understand it.
Can someone suggest how to tamp down this message without suppressing other possible warning messages?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
JSF/Facelets 默认使用 UTF-8 来解码 HTTP 请求参数。 GlassFish 本身默认使用 ISO-8859-1 来解码 HTTP 请求参数。 HTTP 请求参数只能解析和解码一次,每当代码第一次请求请求参数时就会发生这种情况,例如
request.getParameter("name")
。因此,如果在 JSF 将请求参数编码设置为 UTF-8 之前首次请求请求参数,则将使用 ISO-8859-1(错误地)对其进行解析。当 JSF 需要在恢复视图阶段设置请求参数编码如下时,
而请求参数已经解析,则 GlassFish 将准确显示此警告。
不想要的结果是,所有这些 HTTP 请求参数可能最终出现在 Mojibake 中。表单数据最初是使用 UTF-8 提交和编码的。如果您使用不同的字符集(如 ISO-8859-1)解码 UTF-8 数据,则 8 位范围及以上的字符(通常是那些“特殊字符”,如
é
、à
、ö
等将被损坏并最终变成Î
、Ð
、¶
等从技术上讲,正确的解决方案是在 JSF 设置正确的编码之前不请求 HTTP 请求参数。您基本上需要检查在 JSF 恢复视图阶段之前运行的所有代码。 ,例如 servlet 过滤器、阶段侦听器等,如果它们没有这样做
,或者代码超出了您的控制范围,那么您可以告诉 GlassFish 使用 UTF-8 来解码 HTTP。请求参数,这样就可以了当 JSF 想要获取它们时不需要更改,您可以通过将以下条目添加到
/WEB-INF/ 的
文件:
中来实现。 glassfish-web.xml(注意:文件和根条目以前称为< /code> 分别)
sun-web.xml
和注意应该是这是 GlassFish 特有的,当您将 Web 应用程序部署到不同的服务器时,这一切都不起作用。规范的独立于服务器的方法是创建一个 servlet 过滤器,它基本上在
doFilter( )
方法:并确保它在需要收集任何 HTTP 请求参数的任何其他过滤器之前进行映射。
更新:至于为什么GlassFish会提前设置,可能是PrimeFaces造成的。另请参阅此相关问题:通过 PrimeFaces 输入组件检索的 Unicode 输入已损坏< /a>.
JSF/Facelets uses by default UTF-8 to decode HTTP request parameters. GlassFish itself uses by default ISO-8859-1 do decode HTTP request parameters. HTTP request parameters can be parsed and decoded only once and this happens whenever a request parameter is requested by the code for the first time like so
request.getParameter("name")
. So, if a request parameter is requested for the first time before JSF has set the request parameter encoding to UTF-8, then it will (incorrectly) be parsed using ISO-8859-1.When JSF needs to set the request parameter encoding during restore view phase as follows,
while the request parameters are already parsed, then GlassFish will show exactly this warning.
The unwanted consequence is, all those HTTP request parameters may possibly end up in Mojibake. The form data is originally submitted and encoded using UTF-8. If you decode UTF-8 data using a different charset like ISO-8859-1, then the characters in 8-bit range and beyond (usually, it are those "special characters" like
é
,à
,ö
, etc. will be corrupted and end up iné
,Ã
,ö
, etc.Technically, the right solution is to not request a HTTP request parameter before JSF has set the right encoding. You basically need to check all the code which runs before JSF's restore view phase, such as servlet filters, phase listeners, etc if they aren't doing that.
If you can't seem to find it, or the code is beyond your control, then you can tell GlassFish to use UTF-8 instead to decode HTTP request parameters, so that it doesn't need to be changed when JSF want to get them. You can do that by adding the following entry to the
<glassfish-web-app>
of your/WEB-INF/glassfish-web.xml
file:(note: the file and root entry is previously called
sun-web.xml
and<sun-web-app>
respectively)Noted should be that this is specific to GlassFish and this all won't work when you deploy the webapp to a different server. The canonical server-independent approach is to create a servlet filter which does basically the following job in
doFilter()
method:and make sure that it's been mapped before any other filter which needs to collect any HTTP request parameters.
Update: as to why GlassFish has set it beforehand, it's possibly caused by PrimeFaces. See also this related question: Unicode input retrieved via PrimeFaces input components become corrupted.