2012-06-12 41 views
10

Tengo un formulario de búsqueda en JSF que se implementa utilizando un componente de autocompletado RichFaces 4 y la siguiente página JSF 2 y Java Bean. Uso Tomcat 6 & 7 para ejecutar la aplicación.Codificación UTF-8 de parámetros GET en JSF

... 
<h:commandButton value="#{msg.search}" styleClass="search-btn" action="#{autoCompletBean.doSearch}" /> 
... 

En el AutoCompleteBean

public String doSearch() { 

    //some logic here 
    return "/path/to/page/with/multiple_results?query=" + searchQuery + "&amp;faces-redirect=true"; 

} 

Esto funciona bien siempre y cuando todo en el canto "searchQuery" String está en Latin-1, que no funciona si está fuera de América-1.

Por ejemplo, una búsqueda de "bodø" se codificará automáticamente como "bod% F8". Sin embargo, la búsqueda de "Kra Ðong" no funcionará porque no puede codificar "Ð".

Ahora he intentado varios enfoques diferentes para resolver esto, pero ninguno de ellos funciona.

  • He intentado codificar el searchQuery yo mismo usando URLEncode, pero esto solo lleva a la doble codificación ya que% está codificado como% 25.
  • He intentado usar java.net.URI para obtener la codificación, pero da el mismo resultado que URLEncode.
  • He intentado encender UTF-8 en Tomcat usando URIEncoding = "UTF-8" en el Conector, pero esto solo empeora ese problema ya que los caracteres que no son ASCII no funcionan en absoluto.

Así que a mis preguntas:

  1. ¿Puedo cambiar la forma de JSF 2 codifica los parámetros GET?
  2. Si no puedo cambiar la forma en que JSF 2 codifica los parámetros GET, ¿puedo cambiar la codificación y hacerlo manualmente?
  3. ¿Estoy haciendo algo extraño aquí? Esto parece algo que debería ser compatible desde el primer momento, pero no puedo encontrar otros con el mismo problema.

Respuesta

9

Creo que has golpeado un error de esquina en JSF. La cadena de consulta está codificada en URL por ExternalContext#encodeRedirectURL() que usa la codificación de caracteres de respuesta obtenida por ExternalContext#getResponseCharacterEncoding(). Sin embargo, aunque JSF utiliza UTF-8 como codificación de caracteres de respuesta, esto solo se establece si la vista se va a representar realmente, no cuando la respuesta se debe redirigir, por lo que la codificación del carácter de respuesta aún devuelve la plataforma predeterminada de ISO-8859-1 que hace que tus personajes tengan codificación URL usando esta codificación incorrecta.

Lo he informado como issue 2440. Mientras tanto, tu mejor opción es establecer explícitamente la codificación de caracteres de respuesta de antemano.

FacesContext.getCurrentInstance().getExternalContext().setResponseCharacterEncoding("UTF-8"); 

Tenga en cuenta que esto todavía requiere que el propio contenedor utiliza la misma codificación de caracteres para decodificar la URL de solicitud, por lo que sin duda necesita para establecer URIEncoding="UTF-8" en la configuración de Tomcat. Esto no ensuciará más a los personajes, ya que serán realmente UTF-8 ahora.

+0

Sí, eso funciona. ¡Gracias! – oyse

+0

De nada :) – BalusC

0

La única codificación de caracteres aceptada para HTTP URLs y encabezados es US-ASCII, necesita codificar URL estos caracteres para enviarlos de vuelta a la aplicación. forma más sencilla de hacer esto en Java sería:

public String doSearch() { 

    //some logic here 
    String encodedSearchQuery = java.net.URLEncoder.encode(searchQuery, "UTF-8"); 
    return "/path/to/page/with/multiple_results?query=" + encodedSearchQuery + "&amp;faces-redirect=true"; 

} 

Y entonces debería funcionar para cualquier carácter que se utiliza.

+0

JSF lo hace implícitamente. Al menos, se supone que debe hacer eso. Lee la pregunta una vez más. P.ej. * "He intentado codificar el searchQuery my self usando URLEncode, pero esto solo lleva a una doble codificación ya que% está codificado como% 25." * – BalusC