viernes, 19 de agosto de 2011

Struts 1: Descargando la excepción en un DownloadAction



En un proyecto para el cliente requeríamos descargar un PDF que se generaba de manera dinámica. Así que decidimos usar el DownloadAction de Struts 1 que está disponible en un paquete llamado "struts-extras". Por ciertos inconvenientes en el proyecto la aplicación fallaba en el ambiente del cliente y teníamos que estar visitando los logs para ver las excepciones. Dependiendo de la configuración de un servidor, buzear en logs puede ser una tarea sumamente laboriosa lo cual fue en mi caso particular.

Así que para facilitar el análisis decidí agregar un pedazo de código que cuando atajara la excepción, esta misma se pudiera descargar como un ".txt". Utilizé una función que me encontré en Internet que convierte el StackTrace a un String. Después el String se convierte a un arreglo de Bytes que se descarga finalmente como un TXT. Dejo el código a disposición.


import java.io.ByteArrayInputStream;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;

public class OutputPDFAction extends DownloadAction {

@Override
protected StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {

try{
// Code might throw an exception.

response.setHeader("Content-disposition", "attachment; filename=patient_diary.pdf");
String contentType = "application/x-download";

return new ByteDownloadStreamInfo(contentType,abyte0);

}
catch(Throwable throwable)
{
response.setHeader("Content-disposition", "attachment; filename=error.txt");
String contentType = "application/x-download";

return new ByteDownloadStreamInfo(contentType,
stackTraceToString(throwable).getBytes());
}
}

private String stackTraceToString(Throwable e) {
String retValue = null;
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
e.printStackTrace(pw);
retValue = sw.toString();
} finally {
try {
if(pw != null) pw.close();
if(sw != null) sw.close();
} catch (IOException ignore) {}
}
return retValue;
}


class ByteDownloadStreamInfo implements StreamInfo {

private byte[] bytes;
private String contentType;

public ByteDownloadStreamInfo(String contentType, byte[] bytes) {

this.bytes = bytes;
this.contentType=contentType;
}

public String getContentType() {
return this.contentType;
}

public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.bytes);
}
}
}


No hay comentarios:

Publicar un comentario