2010-09-17 9 views
12

Mi servlet simplemente no usará UTF-8 para respuestas JSON.¿Por qué mi Servlet no responde a las solicitudes JSON en UTF-8?

MyServlet.java:

public class MyServlet extends HttpServlet { 

    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception { 

    PrintWriter writer = res.getWriter(); 

    res.setCharacterEncoding("UTF-8"); 
    res.setContentType("application/json; charset=UTF-8"); 

    writer.print(getSomeJson()); 
    } 
} 

Pero caracteres especiales no aparecen, y cuando compruebo las cabeceras que estoy volver a estar en Firebug, veo Content-Type: application/json;charset=ISO-8859-1.

Hice un grep -ri iso . en mi directorio Servlet, y no se me ocurrió nada, por lo que en ninguna parte estoy estableciendo explícitamente el tipo a ISO-8859-1.

También debo especificar que estoy ejecutando esto en Tomcat 7 en Eclipse con un objetivo J2EE como entorno de desarrollo, con Solaris 10 y lo que ellos llaman su entorno de servidor web (alguien más administra esto) como entorno de producción, y el comportamiento es el mismo

También he confirmado que la solicitud enviada es UTF-8, y solo la respuesta es ISO-8859-1.

actualización

he modificado el código para reflejar que estoy llamando PrintStream antes de establecer la codificación de caracteres. Lo omití de mi ejemplo original, y ahora me doy cuenta de que este fue el origen de mi problema. Leí here que tiene que establecer la codificación de caracteres antes de llamar al HttpServletResponse.getWriter(), o getWriter lo configurará en ISO-8859-1 para usted.

Este fue mi problema. Por lo tanto, el ejemplo anterior debe ajustarse a

public class MyServlet extends HttpServlet { 

    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception { 

    res.setCharacterEncoding("UTF-8"); 
    res.setContentType("application/json"); 

    PrintWriter writer = res.getWriter(); 
    writer.print(getSomeJson()); 
    } 
} 
+1

Gracias por su "Actualización", eso es exactamente lo que estoy buscando: Primero establecer la codificación de caracteres, Segundo obtener el escritor. –

Respuesta

4

Una vez que la codificación está configurada para una respuesta, no se puede cambiar.

La manera más fácil de forzar UTF-8 es crear su propio filtro, que es el primero en echar un vistazo a la respuesta y establecer la codificación.

Eche un vistazo a how Spring 3.0 does this. Incluso si no puede usar Spring en su proyecto, tal vez pueda obtener algo de inspiración (asegúrese de que la política de su compañía le permita obtener inspiración de las licencias de código abierto).

+0

Tiene razón acerca de no poder cambiar la codificación. Lo estaba configurando dos veces, pero no explícitamente. Lo estaba haciendo implícitamente con getWriter. Ver mi pregunta actualizada Gracias por su respuesta y +1. –

1

El código se ve bien. O bien no está ejecutando el código que cree que está ejecutando, o hay algún Filter o proxy en algún lugar de la cadena de solicitud-respuesta que modifica el tipo de contenido de esa manera.

+0

No sé dónde podría estar pasando esto a menos que sea el comportamiento predeterminado de mi entorno. Hay un archivo fuente y lo escribí desde cero. Pero este es también mi primer Servlet, así que no sé qué es un 'Filtro'. –

+0

Nada más en '/ WEB-INF/web.xml' de webapp? ¿Qué versión de Tomcat exactamente? ¿Modificó algo en su archivo '/ conf/web.xml' después de descargarlo/instalarlo? – BalusC

+0

Nada más allí. Ver mi pregunta actualizada –

0

Aparte de un problema específico, debería considerar obtener flujo de salida, utilizando la biblioteca JSON para escribir contenidos directamente como JSON codificado en UTF-8; no hay beneficio para usar escritores. Algunos paquetes JSON solo funcionan con cadenas, lo cual es desafortunado, pero la mayoría permite el uso de transmisiones más eficientes (más seguras y más eficientes ya que el analizador/generador puede manejar aspectos de escape y codificación juntos).

+0

Gracias por su sugerencia. Voy a ver esto. Este es mi primer servlet, por lo que no estoy muy familiarizado con las bibliotecas disponibles. Estoy obligado a usar lo que esté disponible en nuestro entorno predeterminado de Solaris 10. –

Cuestiones relacionadas