sábado, 15 de noviembre de 2008

Tratamiento de errores en XMLHttpRequest

Tras la primera entrada de prueba en mi blog hoy a tratar un problema que hay usando FF 3.0 al retornar errores HTTP desde Java con sendError.

En el navegador usando JavaScript hacemos una llamada AJAX al servidor mediante la clase XMLHttpRequest y el método send.
Puede ocurrir que se produzca una excepción en el tratamiento del código Java del servidor. A mi me gusta en ese caso retornar un error HTTP en vez de un XML con un mensaje de error. Desde Java es tan sencillo como:


response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR , "Ha habido un error");


Luego desde JavaScript muestro un mensaje del estilo:


if(xmlHttpRequest.status != 200) {
alert(xmlHttpRequest.status + "=" + xmlHttpRequest.statusText);
}


Hasta aquí nada que no sepamos ya todos.

El problema está en si ponéis caracteres por encima del 127, como acentos o la ñ, no se ve bien el mensaje.

Probad ahora en FF 3 con ésto:


response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR , "El problema está en el acento");


y veréis una pantalla como la siguiente:



Como se puede apreciar ha salido un churro de texto.
Si probáis lo mismo en IE 6.0 si que se ve perfectamente:



Tras googlear un poco y no encontrar nada, me puse a hacer pruebas a ver si sonaba la flauta y al final he encontrado una solución medio buena.

Para que funcione en FF 3.0 uso el siguiente truco:


String msg=new String("El problema está en el acento".getBytes("UTF-8"));
response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR , msg);


Es decir lo codifico yo a mano a UTF-8.
Ahora ya se muestra correctamente en FF 3.0:



El problema ahora es que en IE 6.0 ya no se ve bien:



Como apreciamos viendo los carácteres que aparecen es el típico error de cuando algo está en UTF-8 y nosotros pensamos que no. Para solucionar esto no tenemos mas que decodificar ese texto en UTF-8.Para ello podemos por ejemplo utilizar la clase Utf8 que se encuentra en http://www.webtoolkit.info/javascript-utf8.html quedando el código de la siguiente forma:


alert(xmlHttpRequest.status + "=" + Utf8.decode(xmlHttpRequest.statusText));


Y ya vemos el texto bien:



Sin embargo , ahora lo hemos vuelto a estropear en FF 3.0, así que la única solución que he encontrado es ver desde JavaScript si estamos en FF o en IE y usar el decode o no:


var msg;
if (isIE()) {
msg=Utf8.decode(xmlHttpRequest.statusText);
alert(xmlHttpRequest.status + "=" + msg);
} else {
msg=xmlHttpRequest.statusText;
alert(xmlHttpRequest.status + "=" + msg);
}


El problema ahora lo tenemos en saber si es IE o FF. Mirando un poco en google hay páginas con snippets que nos lo indican. Pero con cada versión nueva de navegador pueden dejar de funcionar, además, tampoco sabremos si en versiones posteriores de FF o IE cambiará la forma en la que funciona XMLHttpRequest.statusText, por lo que la solución que he encontrado no es muy robusta. :-(

Otra forma se programarlo es decidir desde el servidor si estamos en FF o IE y realizar el getBytes o no.


String msg="El problema está en el acento";
String realMsg;
if (isIE()==false) {
realMsg=new String(msg.getBytes("UTF-8"));
} else {
realMsg=msg;
}

response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR , realMsg);


La ventaja de este otro método es que te evitas el hacer el Utf8.decode desde JavaScript y por lo tanto tener que añadir la clase Utf8.

Para acabar y como dije al principio todo esto se puede evitar si retornamos un XML de error en vez de retornar un error HTTP, pero eso ya depende de cada uno y de lo que necesite.

lunes, 1 de septiembre de 2008

Diseño de librerías

Hoy empiezo mi primer blog.
La entrada siguiente Sending email in Java: There's more than one way habla sobre como enviar un eMail en Java. La forma "oficial" es usando JavaMail. Lo que me ha parecido interesante de esta entrada en ver como "critican" (en el buen sentido) el diseño de JavaMail.
Lo que dicen es que JavaMail fué pensado para grandes sitios y que para usa simple aplicación que necesita enviara eMails queda un poco grande.
A mi no me parece muy enrevesado, he visto librerías mucho peores, pero si que es interesante ver como alguien da una pequeña orientación del "porqué" del diseño una librería.
Al ver el API de una librería muchas veces me hago la pregunta, ¿Por qué hacen las cosas tan difíciles? Y siempre es de agradecer una respuesta.
Al final comentan la librería Apache Commons Mail que sobre JavaMail crear un envoltorio para hacerlo más fácil.

Por último a ver si me compro el siguiente libro Practical API Design: Confessions of a Java™ Framework Architect y aprendo un poco más del tema.