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:

miércoles, 8 de diciembre de 2010

Joomla: Insertar código HTML personalizado en artículo

Uno esperaría que esto fuera una opción bastante sencilla y directa. En efecto cuando uno abre el editor encuentra el botón HTML para insertar contenido en dicho lenguage.


Necesitaba colocar un mapa de Google empotrado en la página insertando el código que Google provee. Lo inserté y guardé pero luego me di cuenta que el código original:


<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps/ms?ie=UTF8&hl=es&t=h&msa=0&msid=117809438193952087338.0004964e1a9e9e1fcf96f&ll=9.938713,-84.04923&spn=0.007397,0.00912&z=16&output=embed"></iframe><br /><small>Ver <a href="http://maps.google.com/maps/ms?ie=UTF8&hl=es&t=h&msa=0&msid=117809438193952087338.0004964e1a9e9e1fcf96f&ll=9.938713,-84.04923&spn=0.007397,0.00912&z=16&source=embed" style="color:#0000FF;text-align:left">MET - UCR</a> en un mapa más grande</small>


había cambiado:



Parece que el editor hace ciertas transformaciones al código HTML que impiden, en este caso particular, poder usar el código del mapa de Google. Investigando un poco en Internet, en un sitio daban un tip que consiste en crear un super usuario "noeditor" seleccionando la opción de no usar ningún editor.



Ingrese a Joomla con este usuario, edite el código y de esta manera pude insertar el código HTML sin que Joomla lo modificara. Uno podría también editar las opciones de su propio usuario, pero resulta más práctico tener un usuario asignado para este tipo de ocasiones.

jueves, 2 de diciembre de 2010

Diferencia entre Clase Abstracta e Interface


Potencial pregunta de entrevista de trabajo. La diferencia puede parecer obvia en el código, pero en términos de funcionalidad existe un traslapo donde tenemos que detenernos por un momento a reflexionar, si es que no lo hemos hecho, por qué debemos usar una opción o la otra.

Lo primero que recordamos de una clase abstracta es que no podemos instanciarla. La clase abstracta se usa como interfaz de las subsecuentes clases que harán conversión hacia arriba ("upcasting"). Podemos describir el upcasting como la acción de declarar una variable de una clase base (abstracta en la mayoría de los casos), pero instanciando una implementación de la misma. Esto da vida al comportamiento polifórmico.

MyAbstract myAbstract = new MyImplementation();

Veamos un ejemplo de una clase abstracta reloj.


public abstract class Watch {

/* Instance variables */

protected int seconds;
protected int minutes;
protected int hours;

/* Constructors */

public Watch() {

}

public Watch(int h, int m, int s) {
hours = h;
minutes = m;
seconds = s;
}

// Must override this method.
abstract public void showTime();

/*Getters and setters for the time components.*/

public int getSeconds() {
return seconds;
}

public void setSeconds(int seconds) {
this.seconds = seconds;
}

public int getMinutes() {
return minutes;
}

public void setMinutes(int minutes) {
this.minutes = minutes;
}

public int getHours() {
return hours;
}

public void setHours(int hours) {
this.hours = hours;
}
}


Y ahora la implementación de un reloj dijital.


public class DigitalWatch extends Watch {

public DigitalWatch(int h, int m, int s) {
super(h,m,s);
}

public void showTime() {
System.out.println(hours +":" + minutes + ":" + seconds);
}

public static void main(String[] args) {
Watch myWatch = new DigitalWatch(5, 30, 20);
myWatch.showTime(); // Prints "5:30:20".
}
}


Si intentamos replicar este diseño con el uso de una interfaz vemos que necesitamos mover el código antes localizado en la clase base Watch en la implementación de DigitalWatch.


public interface WatchI {

public void showTime();

}


public class DigitalWatchI implements WatchI{

protected int seconds;
protected int minutes;
protected int hours;

public void showTime() {
System.out.println(hours +":" + minutes + ":" + seconds);
}

public DigitalWatchI(int h, int m, int s) {
hours = h;
minutes = m;
seconds = s;
}

/*Getters and setters for the time components.*/

public int getSeconds() {
return seconds;
}

public void setSeconds(int seconds) {
this.seconds = seconds;
}

public int getMinutes() {
return minutes;
}

public void setMinutes(int minutes) {
this.minutes = minutes;
}

public int getHours() {
return hours;
}

public void setHours(int hours) {
this.hours = hours;
}

public static void main(String[] args) {
WatchI myWatch = new DigitalWatchI(5, 30, 20);
myWatch.showTime(); // Prints "5:30:20".
}
}


Las interfaces en Java se utilizan primordialmente para separar la interfaz de la implementación en una manera más estricta de como lo hace las clases abstractas. Una interfaz no permite del todo algún nivel de implementación en los métodos. Con la clase abstracta si podemos heredar la implementación de una clase a otra.

En resumen:

Classe Abstracta Interface
Contiene tanto métodos ejecutables como métodos
abstractos.
No tiene código de implementación.
Todos sus métodos son abstractos.
Una clase solo puede extender de una única clase abstracta. Una clase puede implementar n número de interfaces.
Puede tener variables de instancia, constructores y cualquiera de los tipos de visibildiad: public, private, protected, ninguno (aka package). No puede tener variables de instancia o constructores y solo puede tener métodos públicos o package.