Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of WARNING: PWC4011: Unable to set request character encoding to UTF-8

Tags:

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?

like image 593
AlanObject Avatar asked Oct 04 '11 04:10

AlanObject


People also ask

How do I change my UTF-8 character set?

Click Tools, then select Web options. Go to the Encoding tab. In the dropdown for Save this document as: choose Unicode (UTF-8). Click Ok.

What does UTF-8 encoding means?

UTF-8 is an encoding system for Unicode. It can translate any Unicode character to a matching unique binary string, and can also translate the binary string back to a Unicode character. This is the meaning of “UTF”, or “Unicode Transformation Format.”

Is UTF-8 character set or encoding?

UTF-8 is a character encoding system. It lets you represent characters as ASCII text, while still allowing for international characters, such as Chinese characters. As of the mid 2020s, UTF-8 is one of the most popular encoding systems.

How do I enable UTF?

Set the option in Visual Studio or programmaticallySelect the Configuration Properties > C/C++ > Command Line property page. In Additional Options, add the /utf-8 option to specify your preferred encoding. Choose OK to save your changes.


1 Answers

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,

request.setCharacterEncoding("UTF-8"); 

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:

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

(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:

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

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.

like image 192
BalusC Avatar answered Oct 23 '22 03:10

BalusC