En el trabajo hemos tenido un gran dolor de cabeza con la codificación de caracteres, nuestro middleware estaba teniendo problemas con acentos, diéresis y "eñes", y por este motivo las respuestas a las peticiones de los web services se tornaron un desastre.
Todo inicio cuando tratamos de mudarnos a un ambiente de desarrollo con alta disponibilidad, ya que en el ambiente anterior funcionaba correctamente, tratamos por todos los medios posibles para corregir el problema, intentamos con:
- Agregar URIEncoding="UTF-8" y useBodyEncodingForURI="true" a la configuración del server.xml
- Agregar el encoding a las opciones de catalina: export CATALINA_OPTS= Dfile.encoding="UTF-8"
- Agregar también el encoding en las opciones de java: export JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding="UTF-8"
- Agregar las locale al usuario que ejecuta el proceso tomcat
Y nada parecía funcionar, hasta que por fin @NataS encontró algo que finalmente nos ayudo a resolver nuestro problemita que nos había consumido muchas horas.
Pues resulta que en las configuraciones nuevas de nuestros servidores estaba habilitada la opción RequestDumperValve en el server.xml, y que hace ese tal RequestDumperValve?, desde la documentación de tomcat:
"The Request Dumper Valve is a useful tool in debugging interactions with a client application (or browser) that is sending HTTP requests to your Tomcat-based server. When configured, it causes details about each request processed by its associated Engine, Host, or Context to be logged according to the logging configuration for that container.
WARNING: Using this valve has side-effects. The output from this valve includes any parameters included with the request. The parameters will be decoded using the default platform encoding. Any subsequent calls to request.setCharacterEncoding() within the web application will have no effect. NOTE: Since all parameters are included in the output, the InputStream is consumed for requests made with the method POST and content-type application/x-www-form-urlencoded."
Fuente.
En palabras de Endre Stølsvik:
“Enabling the RequestDumperValve in both 5.5.12 and 5.0.16 (!) messes up the parsing of other-than-ISO-8859-1 incoming parameters.
After using a rather huge bunch of hours, this came down as the result: when this “debug valve” is turned on, it seems to default to ISO-8859-1 when it parses and log-outputs the incoming parameters, thus also implicitly setting the entire Request-object to this enc, so any subsequnt setting to UTF-8 doesn’t matter at all. At least this is true for POST parameters.
For GET parameters, the situation is a little different. Here an explicit setting of URIEncoding to UTF-8 seems to work as it should, while useBodyEncodingForURI doesn’t – it picks up the wrong already implicitly set encoding. (For 5.0.16 I can’t seem to get the latter version to work, and have to use the explicit setting.)
Sorry if my analysis doesn’t hold water, but at least the bug seems to be very consistent.”
Y al parecer nos es especifico de estas versiones, también sucede en la versión 6. Para la versión 7 esta válvula se llama RequestDumperFilter
Entonces tal como se expresa en estas citas, tener activado RequestDumperValve puede tener efectos colaterales, ya que se puede parsear a otra codificación todos los parámetros, y además que, posterior a esto no importa cualquier otra configuración que sea agregada, ya que no será respetada, al menos para las peticiones POST (cuyo método usamos para todas nuestras peticiones).
Tal como dijó rolfje:
Si tienes problemas raros con UTF-8 y Tomcat, busca en tu archivo server.xml una linea parecida a:
<Valve className="org.apache.catalina.valves.RequestDumperValve">
comentala, reinicia tu servidor de aplicaciones y vuelve a intentarlo. Puede que con eso, tus problemas también sean resueltos.