sirve rendered que para internacionalizacion jsf unicode primefaces character-encoding mojibake

rendered - jsf internationalization



La entrada Unicode recuperada a través de los componentes de entrada de PrimeFaces se corrompe (1)

Introducción

Normalmente, JSF / Facelets establecerá la codificación de caracteres del parámetro de solicitud en UTF-8 de forma predeterminada cuando se crea / restaura la vista. Pero si se solicita algún parámetro de solicitud antes de crear / restaurar la vista, entonces es demasiado tarde para establecer la codificación de caracteres adecuada. Los parámetros de solicitud se analizarán solo una vez.

La codificación PrimeFaces falla

Que falló en PrimeFaces 3.x después de la actualización de 2.x es causado por la nueva isAjaxRequest() en PrimePartialViewContext PrimeFaces que verifica un parámetro de solicitud:

@Override public boolean isAjaxRequest() { return getWrapped().isAjaxRequest() || FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().containsKey("javax.faces.partial.ajax"); }

Por defecto, isAjaxRequest() (el de Mojarra / MyFaces, como el código PrimeFaces anterior obtenido por getWrapped() ) comprueba el encabezado de solicitud de la siguiente manera que no afecta la codificación del parámetro de solicitud ya que los parámetros de solicitud no se analizarán cuando se obtiene un encabezado de solicitud:

if (ajaxRequest == null) { ajaxRequest = "partial/ajax".equals(ctx. getExternalContext().getRequestHeaderMap().get("Faces-Request")); }

Sin embargo, isAjaxRequest() puede ser llamado por cualquier oyente de fase o detector de eventos del sistema o alguna fábrica de aplicaciones antes de que la vista sea creada / restaurada. Por lo tanto, cuando utilice PrimeFaces 3.x, los parámetros de la solicitud se analizarán antes de que se establezca la codificación de caracteres adecuada y, por lo tanto, usará la codificación predeterminada del servidor, que generalmente es ISO-8859-1. Esto arruinará todo.

Soluciones

Hay varias formas de solucionarlo:

  1. Utilice un filtro de servlet que establezca ServletRequest#setCharacterEncoding() con UTF-8. Establecer la codificación de respuesta por ServletResponse#setCharacterEncoding() es, por cierto, innecesario, ya que no se verá afectado por este problema.

    @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); } // ... }

    Solo necesita tener en cuenta que HttpServletRequest#setCharacterEncoding() solo establece la codificación para los parámetros de solicitud POST, no para los parámetros de solicitud GET. Para los parámetros de solicitud GET, aún deberá configurarlo en el nivel del servidor.

    Si usa la biblioteca de utilidades JSF OmniFaces , dicho filtro ya está provisto en la caja, el CharacterEncodingFilter . Simplemente instálelo de la siguiente manera en web.xml como primera entrada de filtro:

    <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.omnifaces.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

  2. Vuelva a configurar el servidor para usar UTF-8 en lugar de ISO-8859-1 como codificación predeterminada. En el caso de Glassfish, eso sería una cuestión de agregar la siguiente entrada a <glassfish-web-app> del archivo /WEB-INF/glassfish-web.xml :

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

    Tomcat no lo admite. Tiene el atributo URIEncoding en la entrada <Context> , pero esto se aplica solo a las solicitudes GET, no a las solicitudes POST.

  3. Informar como un error a PrimeFaces. ¿Existe alguna razón legítima para verificar que la solicitud HTTP sea una solicitud de Ajax al verificar un parámetro de solicitud en lugar de un encabezado de solicitud como lo haría con JSF estándar y, por ejemplo, jQuery? El JavaScript core.js PrimeFaces está haciendo eso. Sería mejor si lo hubiera establecido como un encabezado de solicitud de XMLHttpRequest .

Soluciones que NO funcionan

Quizás te encuentres con las "soluciones" a continuación en algún lugar de Internet mientras investigas este problema. Esas soluciones no funcionarán en este caso específico. La explicación sigue.

  • Configuración de prólogo XML:

    <?xml version=''1.0'' encoding=''UTF-8'' ?>

    Esto solo le dice al analizador XML que use UTF-8 para decodificar el origen XML antes de construir el árbol XML a su alrededor. El analizador XML que Facelts realmente usa es SAX durante el tiempo de compilación de la vista JSF. Esta parte no tiene nada que ver con la codificación de solicitud / respuesta HTTP.

  • Configuración de metaetiqueta HTML:

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    La metaetiqueta HTML se ignora cuando la página se sirve a través de HTTP a través de http(s):// URI. Solo se ha usado cuando la página está guardada por el cliente como un archivo HTML en el sistema de disco local y luego se vuelve a abrir con un file:// URI en el navegador.

  • La configuración del formulario HTML acepta el atributo charset:

    <h:form accept-charset="UTF-8">

    Los navegadores modernos ignoran esto. Esto solo tiene efecto en el navegador Microsoft Internet Explorer. Incluso entonces lo está haciendo mal. Nunca lo use Todos los navegadores web reales usarán el atributo de conjunto de caracteres especificado en el encabezado Content-Type de la respuesta. Incluso MSIE lo hará de la manera correcta, siempre y cuando no especifique el atributo accept-charset .

  • Estableciendo el argumento JVM:

    -Dfile.encoding=UTF-8

    Esto solo lo utiliza Oracle (!) JVM para leer y analizar los archivos fuente de Java.

Cuando todavía estaba usando PrimeFaces v2.2.1, pude escribir entradas Unicode como chino con un componente de entrada PrimeFaces como <p:inputText> y <p:editor> , y recuperar la entrada en buen estado en el método de bean administrado .

Sin embargo, después de actualizar a PrimeFaces v3.1.1, todos esos personajes se convierten en Mojibake o signos de interrogación. Solo la entrada en latín viene bien, son los caracteres chinos, árabes, hebreos, cirílicos, etc. que se deforman.

¿Cómo es esto causado y cómo puedo resolverlo?