Mostrando entradas con la etiqueta Struts 1X. Mostrar todas las entradas
Mostrando entradas con la etiqueta Struts 1X. Mostrar todas las entradas

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);
}
}
}


viernes, 31 de diciembre de 2010

Struts 1X: Cómo subir un archivo ("uploading")?

Dejo como referencia este código para poder crear un formulario en cual podamos subir (aka "upload") un archivo con Struts 1X.

Código JSP:
<html:form action="/snapshotUploadAction.do" method="post" enctype="multipart/form-data">
File : <html:file property="formFile" /> <html:submit />
</html:form>

<c:if test="${not empty fileUploadForm.message}">
<p style="color:red;">${fileUploadForm.message}</p>
</c:if>


Código del ActionForm:


import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;

public class FileUploadForm extends ActionForm {

private static final long serialVersionUID = 1L;

protected FormFile formFile;
protected String message;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public FormFile getFormFile() {
return formFile;
}

public void setFormFile(FormFile formFile) {
this.formFile = formFile;
}
}


Código del Action:


import java.io.File;
import java.io.FileOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import com.eol.core.controller.form.FileUploadForm;

/**
* Basic action to be used to upload files.
* @author gsolano
*
*/
public class FileUploadAction extends Action{

@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {

FileUploadForm uploadForm = (FileUploadForm) form;
FileOutputStream outputStream = null;
FormFile formFile = null;
String path="";
formFile = uploadForm.getFormFile();

if(formFile != null) {
try {
path = getRepositoryPath() + formFile.getFileName();
System.out.println("File will be uploaded to this path: " + path);
outputStream = new FileOutputStream(new File(path));
outputStream.write(formFile.getFileData());

} catch(Exception exception) {
System.out.println(exception);
}
finally {
if (outputStream != null) {
outputStream.close();
}
}
/* Do something with the just uploaded file*/
processUploadedFile(path);
uploadForm.setMessage("The file " + formFile.getFileName() + " was uploaded successfully.");
}
return mapping.findForward("success");
}

/**
*
* @param path
*/
protected void processUploadedFile(String path) {
/*MUST OVERRIDE TO DO SOMETHING WITH THE UPLOADED FILE*/
}

/**
* This path where the file will be uploaded is put in a method to allow
* classes extending to be able to override it.
* @return
*/
protected String getRepositoryPath() {
return getServlet().getServletContext().getRealPath("")+"/";
}
}


Resultado: