Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h3>Introduction</h3> <p>Normally, JSF/Facelets will set the request parameter character encoding to UTF-8 by default already when the view is created/restored. But if any request parameter is been requested <em>before</em> the view is been created/restored, then it's too late to set the proper character encoding. The request parameters will namely be parsed only once.</p> <h3>PrimeFaces encoding fail</h3> <p>That it failed in PrimeFaces 3.x after upgrading from 2.x is caused by the new <code>isAjaxRequest()</code> override in PrimeFaces' <code>PrimePartialViewContext</code> which checks a request parameter:</p> <pre><code>@Override public boolean isAjaxRequest() { return getWrapped().isAjaxRequest() || FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().containsKey("javax.faces.partial.ajax"); } </code></pre> <p>By default, the <code>isAjaxRequest()</code> (the one of Mojarra/MyFaces, as the above PrimeFaces code has obtained by <code>getWrapped()</code>) checks the request header as follows which does not affect the request parameter encoding as request parameters won't be parsed when a request header is obtained:</p> <pre><code> if (ajaxRequest == null) { ajaxRequest = "partial/ajax".equals(ctx. getExternalContext().getRequestHeaderMap().get("Faces-Request")); } </code></pre> <p>However, the <code>isAjaxRequest()</code> may be called by any phase listener or system event listener or some application factory <em>before</em> the view is been created/restored. So, when you're using PrimeFaces 3.x, then the request parameters will be parsed <em>before</em> the proper character encoding is been set and hence use the server's default encoding which is usually ISO-8859-1. This will mess up everything.</p> <h3>Solutions</h3> <p>There are several ways to fix it:</p> <ol> <li><p>Use a <a href="https://stackoverflow.com/tags/servlet-filters/info">servlet filter</a> which sets <a href="http://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html#setCharacterEncoding%28java.lang.String%29" rel="nofollow noreferrer"><code>ServletRequest#setCharacterEncoding()</code></a> with UTF-8. Setting the response encoding by <a href="http://docs.oracle.com/javaee/7/api/javax/servlet/ServletResponse.html#setCharacterEncoding%28java.lang.String%29" rel="nofollow noreferrer"><code>ServletResponse#setCharacterEncoding()</code></a> is by the way unnecessary as it won't be affected by this issue. </p> <pre><code>@WebFilter("/*") public class CharacterEncodingFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); chain.doFilter(request, response); } // ... } </code></pre> <p>You only need to take into account that <code>HttpServletRequest#setCharacterEncoding()</code> only sets the encoding for POST request parameters, not for GET request parameters. For GET request parameters you'd still need to configure it at server level.</p> <p>If you happen to use JSF utility library <a href="http://omnifaces.org" rel="nofollow noreferrer">OmniFaces</a>, such a filter is already provided out the box, <a href="http://showcase.omnifaces.org/filters/CharacterEncodingFilter" rel="nofollow noreferrer">the <code>CharacterEncodingFilter</code></a>. Just install it as below in <code>web.xml</code> as first filter entry:</p> <pre><code>&lt;filter&gt; &lt;filter-name&gt;characterEncodingFilter&lt;/filter-name&gt; &lt;filter-class&gt;org.omnifaces.filter.CharacterEncodingFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;characterEncodingFilter&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;/filter-mapping&gt; </code></pre> <hr></li> <li><p>Reconfigure the server to use UTF-8 instead of ISO-8859-1 as default encoding. In case of Glassfish, that would be a matter of adding the following entry to <code>&lt;glassfish-web-app&gt;</code> of the <code>/WEB-INF/glassfish-web.xml</code> file:</p> <pre class="lang-xml prettyprint-override"><code>&lt;parameter-encoding default-charset="UTF-8" /&gt; </code></pre> <p>Tomcat doesn't support it. It has the <code>URIEncoding</code> attribute in <code>&lt;Context&gt;</code> entry, but this applies to GET requests only, not to POST requests.</p> <hr></li> <li><p>Report it as a bug to PrimeFaces. Is there <em>really</em> any legitimate reason to check the HTTP request being an ajax request by checking a request parameter instead of a request header like as you would do for standard JSF and for example jQuery? The PrimeFaces' <code>core.js</code> JavaScript is doing that. It would be better if it has set it as a request header of <code>XMLHttpRequest</code>.</p></li> </ol> <hr> <h3>Solutions which do NOT work</h3> <p>Perhaps you'll stumble upon below "solutions" somewhere on the Internet while investigating this problem. Those solutions do won't ever work in this specific case. Explanation follows.</p> <ul> <li><p>Setting XML prolog:</p> <pre><code>&lt;?xml version='1.0' encoding='UTF-8' ?&gt; </code></pre> <p>This only tells the XML parser to use UTF-8 to decode the XML source before building the XML tree around it. The XML parser actually being used by Facelts is SAX during JSF <a href="https://stackoverflow.com/questions/31890433/whats-the-view-build-time">view build time</a>. This part has completely nothing to do with HTTP request/response encoding.</p></li> <li><p>Setting HTML meta tag:</p> <pre><code>&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt; </code></pre> <p>The HTML meta tag is ignored when the page is served over HTTP via a <code>http(s)://</code> URI. It's only been used when the page is by the client saved as a HTML file on local disk system and then reopened by a <code>file://</code> URI in browser.</p></li> <li><p>Setting HTML form accept charset attribute:</p> <pre><code>&lt;h:form accept-charset="UTF-8"&gt; </code></pre> <p>Modern browsers ignore this. This has only effect in Microsoft Internet Explorer browser. Even then it is doing it wrongly. Never use it. All real webbrowsers will instead use the charset attribute specified in the <code>Content-Type</code> header of the response. Even MSIE will do it the right way as long as you do not specify the <code>accept-charset</code> attribute.</p></li> <li><p>Setting JVM argument:</p> <pre><code>-Dfile.encoding=UTF-8 </code></pre> <p>This is only used by the Oracle(!) JVM to read and parse the Java source files.</p></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload