pedroescudero.info Sobre programación, tecnología, etc

10jul/080

¿Qué sucede con System.out y System.err en un Servlet?

Depende del servidor de aplicaciones.

Por lo general (en JServ o Weblogic o Tomcat) System.out va 'del lado del cliente' y se ve en el navegador, mientras que System.err va 'del lado del servidor' y es visible en los logs de error y/o en la consola.

public void doGet(HttpServletRequest req, HttpServletResponse res) {
// Dejar que el cliente espere texto plano
resp.setContentType("text/plain");

// Esta línea se mostrará en el explorador
System.out.println("Hola explorador!");

// Esta línea se mostrará en el log de errores o similar
System.err.println("Hola log de errores!");
}

Este comportamiento no siempre se cumple para todos los servidores de aplicaciones, por lo que no es conveniente usarlos. En vez de esto usaremos lo siguiente.

Para enviar texto al cliente (explorador web):

public void doGet(HttpServletRequest req, HttpServletResponse res) {
// Obtener el PrintWriter correcto
PrintWriter pw = resp.getWriter();

// Esta línea se mostrará en el explorador
w.println("Hola explorador!");
}

Para enviar texto al log de errores del servidor:

public void doGet(HttpServletRequest req, HttpServletResponse res) {
// Obtener ServletContext
ServletContext sc = getServletContext();

// Esta linea se mostrará en los logs del servidor de aplicaciones
sc.log("Hola log!");
}

Etiquetado con: , , , No hay comentarios
26jun/080

Comprobar el sistema operativo y el navegador del cliente desde un JSP/Servlet

En ocasiones puede que necesitemos averiguar el sistema operativo y el navegador que está usando el usuario que accede a nuestra página JSP/Servlet. Razones por las que necesitemos descubrirlo pueden ser para seleccionar una hoja de estilo distinta para cada explorador, invitar al usuario a cambiarse a Linux, recordarle que Internet Explorer es una mierda y que usandolo perjudica al desarrollo de la web, recomentarle Firefox, no dejarle ver la página hasta que se actualice si usa Internet Explorer 6 o anterior, o cualquier otra imposición parcial y subjetiva que queramos.

Para comprobar ambos datos necesitamos leer de la cabecera de la petición el atributo User-Agent de la siguiente manera.

String userAgent = request.getHeader( "User-Agent" );

Esto nos devuelve la cadena de texto que la aplicación que usamos para navegar por la web propaga en la cabecera. Algunos ejemplos.

Firefox 3 bajo Windows: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9) Gecko/2008052906 Firefox/3.0

IE 7 bajo Windows: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 1.1.4322; .NET CLR 3.0.04506.648)

Ahora solo nos quedaría averiguar a partir de la cadena ambos datos. Una manera simple de detectar los principales exploradores y sistemas operativos sin tener en cuenta versiones.

String SO="Desconocido", browser="Desconocido";

//Comprobamos el sistema operativo
if(userAgent.contains("Windows"))
{
SO="Windows";
}
if(userAgent.contains("Linux"))
{
SO="Linux";
}
if(userAgent.contains("Mac"))
{
SO="Mac OS";
}

//Comprobamos el explorador web
if(userAgent.contains("MSIE"))
{
browser="Internet Explorer";
}
if(userAgent.contains("Opera"))
{
browser="Opera";
}
if(userAgent.contains("Firefox"))
{
browser="Firefox";
}
if(userAgent.contains("Safari"))
{
browser="Safari";
}

Para una comprobación mas precisa puedes consultar esta base de datos de cadenas User-Agent.

Etiquetado con: , , , No hay comentarios
26may/080

Problemas de cotejamiento con Java, iText y JSP (Actualización)

Atendiendo a la documentación veamos las opciones que hay para cambiar la codificación de una String. La primera opción sería usar este constructor, como hacíamos en el ejemplo publicado anteriormente.

String(byte[] bytes, String charsetName)
Constructs a new String by decoding the specified array of bytes using the specified charset.

Según dice: "Construye una nueva String decodificando el array de bytes usando el juego de caracteres especificado". Usando esto decodificamos el array, que está ya codificado en un juego de caracteres, usando la codificación de otro juego de caracteres que escojamos. Esto es válido para los caracteres que ocupan posiciones compartidas en ambos juegos de caracteres, no para aquellos que no están incluidos en ambos que se siguen viendo mal.

Por otro lado tenemos el siguiente método.

byte[] getBytes(String charsetName)
Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.

"Codifica este String en una secuencia de bytes usando el juego de caracteres nombrado y guardando el resultado en un nuevo array de bytes". Es decir, este método si traduce entre juegos de caracteres (codifica los bytes según la codificación del nuevo juego de caracteres), consiguiendo con esto que todos los caracteres se vean correctamente.

Para recodificar correctamente una String a UTF-8 usaremos entonces la siguiente línea.

String recodificada = new String(vieja.getBytes("UTF-8"));

Ver post anterior