lunes, 31 de marzo de 2008

Visita a la Sede de Google

Navegando por internet encontre este interesante informe de un canal argentino donde se muestra como es que viven la gente de google.

Primer informe:

domingo, 30 de marzo de 2008

Insertar un objeto java.sql.Date en SQL Server 2000

En ocasiones queremos saber como insertar un tipo de dato Date del paquete java.sql, normalmente para hacerlo realizamos una conversión CASTING en la sentencia SQL que se le manda a la base de datos, p.e

INSERT INTO ... VALUES(..., convert(varchar,DateColumn,103)...)

En el caso de que no deseamos realizar esa conversion, tenemos el siguiente código:

USE pubs
GO
CREATE TABLE test(test_varchar VARCHAR(255), test_date DATETIME)
GO


/*
* Main.java
*/

package testinsertdate;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
*
* @author hugo
*/
public class Main {

/** Creates a new instance of Main */
public Main() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) throws ParseException {
int result = 0;
Connection con = null;
PreparedStatement ps = null;

SimpleDateFormat fecha = new SimpleDateFormat( "dd/MM/yyyy" );

try{
ConnectionFactory cf = new ConnectionFactory( ConnectionFactory.TYPE_MSSQL,
"localhost", "pubs" );
con = cf.getConnection( "sa", "sa" );
ps = con.prepareStatement( "INSERT INTO test VALUES( ?, ? )" );
ps.setString( 1, "test2" );
ps.setDate( 2, new Date( fecha.parse( "15/02/1982" ).getTime() ) );

ps.executeUpdate();
System.out.println( "Conversion sin excepcion!" );
}catch( SQLException sqle ){
sqle.printStackTrace();
}catch( ParseException pe){
pe.printStackTrace();
}finally{
if( ps != null ) ConnectionFactory.close(ps);
if( con != null ) ConnectionFactory.close(con);
}
}
}
Enlaces de interes:
La clase ConnectionFactory ya lo vimos en el el Post de Conexión con SQL Server 2005
Saludos a todos ;)

VT de PHP y MySQL

Esta es una de las primeros videos tutoriales que iré introduciendo en este blog sobre php y otras tecnologías :)

FileUpload Subida de ficheros al servidor

Descargar ficheros es sumamente sencillo desde el servidor, el problema surge cuando queremos subirlos, los JSP y Servlets de Java no tienen mecanismos para poder manejar la subida de ficheros desde formularios, siendo un problema tratar de extraer el contenido desde HTTP request. Una mejor opcion que nos puede ayudar es utilizar librerias de terceros.

Existe una robusta libreria open-source diseñada para este propósito del paquete
Apache Jakarta Commons FileUpload.

Requerimientos

  • Descargar la libreria Jakarta Commons FileUpload 1.2.1: commons-fileupload-1.2.1.jar
  • Ademas de esta libreria necesitaremos otra de complemento interno de Commons FileUpload llamada Jakarta Commons IO librarie: commons-io-1.4.jar. En este articulo se asume que usted esta utilizando estas librerias.
Software de prueba

El código ha sido probado en un entorno de Java EE5 con Tomcat 5.5.17.

Instalando Apache Jakarta Commons FileUpload y IO en el contenedor como Tomcat

El proximo paso es copiar los archivos jar en el directorio $CATALINA_HOME/webapps/NameProyect/WEB-INF/lib de su aplicación.


Diseñar el formulario


Para subir los ficheros al servidor debemos de crear un formulario un poco especial de tipo POST y MultiPart y que la peticion la dirija a un Servlet: subir.jsp
<form method="POST" enctype="multipart/form-data"
action="<%= request.getContextPath()%>/UploadFile">
Por favor, seleccione el trayecto del fichero a cargar
<br><input type="file" name="fichero">
<input type="submit">
</form>


getContextPatch() obtiene la ruta de su aplicación es este caso "/NameProyect"
Figura 1: formulario JSP para subir un archivo al servidor

Creando nuestro Servlet
Ahora hay que crear el Servlet bajo el nombre de UploadFile.java donde se mostará la forma básica de subir ficheros y como configurar algunos aspectos de la subida para un mejor control, como p.e el limitar el tamaño del fichero:
package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.File;

import java.util.List;
import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


/**
*
* @author hugo
* @version
*/
public class UploadFile extends HttpServlet {

private String dirUploadFiles; //directorio donde se guardara los archivos


protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

// 1. obtengo el directorio donde guardare los archivos, desde un parametro de
// contexto en el archivo web.xml
dirUploadFiles = getServletContext().getRealPath( getServletContext().getInitParameter( "dirUploadFiles" ) );

// 2. Si la peticion es de tipo multi-part,
// static boolean isMultipartContent() devuelve true/false
if( ServletFileUpload.isMultipartContent( request ) ){

// 3. crear el arhivo factory
// DiskFileItemfactory es una implementacion de FileItemfactory
// esta implementacion crea una instacia de FileItem que guarda su
// contenido ya sea en la memoria, para elementos pequeños,
// o en un archivo temporal en el disco, para los
// elementos de mayor tamaño
FileItemFactory factory = new DiskFileItemFactory();


// 4. crear el servlet upload
// es un API de alto nivel para procesar subida de archivos
// Por defecto la instancia de ServletFileUpload tiene los siguientes valores:
// * Size threshold = 10,240 bytes. Si el tamaño del archivo está por debajo del umbral,
// se almacenará en memoria. En otro caso se almacenara en un archivo temporal en disco.
// * Tamaño Maximo del cuerpo de la request HTTP = -1.
// El servidor aceptará cuerpos de request de cualquier tamaño.
// * Repository = Directorio que el sistema usa para archivos temporales.
// Se puede recuperar llamando a System.getProperty("java.io.tmpdir").
ServletFileUpload upload = new ServletFileUpload( factory );
/* 5. declaro listUploadFiles
* Contendrá una lista de items de archivo que son instancias de FileItem
* Un item de archivo puede contener un archivo para upload o un
* campo del formulario con la estructura simple nombre-valor
* (ejemplo: <input name="text_field" type="text" />)
*
* Podemos cambiar las opciones mediante setSizeThreshold() y setRespository()
de la clase DiskFileItemFactory y el
método setSizeMax() de la clase ServletFileUpload, por ejemplo:

DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
diskFileItemFactory.setSizeThreshold(40960); // bytes

File repositoryPath = new File("/temp");
diskFileItemFactory.setRepository(repositoryPath);

ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
servletFileUpload.setSizeMax(81920); // bytes

*
*/
// limito a 300 Kb el humbral del tamaño del archivo a subir
// Long.parseLong( getServletContext().getInitParameter( "maxFileSize" ) )
upload.setSizeMax( new Long( getServletContext().getInitParameter( "maxFileSize" ) ).longValue() ); // 1024 x 300 = 307200 bytes = 300 Kb

List listUploadFiles = null;
FileItem item = null;

try{
// 6. adquiere la lista de FileItem asociados a la peticion
listUploadFiles = upload.parseRequest( request );

/* 7. Iterar para obtener todos los FileItem
* vamos a trabajar con generalidad
* programaremos como si quisieramos leer todos los
* campos sean 'simples' o 'file'. Por ello iteramos
* sobre todos los FileItem que recibimos:
* Los parámetros simples los diferenciaremos de los parámetros 'file'
* por medio del método isFormField()
*/
Iterator it = listUploadFiles.iterator();
while( it.hasNext() ){
item = ( FileItem ) it.next();
// 8. evaluamos si el campo es de tipo file, para subir al servidor
if( !item.isFormField() ){
//9. verificamos si el archivo es > 0
if( item.getSize() > 0 ){
// 10. obtener el nombre del archivo
String nombre = item.getName();
// 11. obtener el tipo de archivo
// e. .jpg = "image/jpeg", .txt = "text/plain"
String tipo = item.getContentType();
// 12. obtener el tamaño del archivo
long tamanio = item.getSize();
// 13. obtener la extension
String extension = nombre.substring( nombre.lastIndexOf( "." ) );

out.println( "Nombre: " + nombre + "<br>");
out.println( "Tipo: " + tipo + "<br>");
out.println( "Extension: " + extension + "<br>");
// 14. determinar si el caracter slash es de linux, o windows
//String slashType = ( nombre.lastIndexOf( "\\" ) > 0 ) ? "\\" : "/"; // Windows o Linux
// 15. obtener la ultima posicion del slash en el nombre del archivo
//int startIndex = nombre.lastIndexOf( slashType );
// 16. obtener el nombre del archivo ignorando la ruta completa
//String myArchivo = nombre.substring( startIndex + 1, nombre.length() );
// 17. Guardo archivo del cliente en servidor, con un nombre 'fijo' y la
// extensión que me manda el cliente,
// Create new File object
File archivo = new File( dirUploadFiles, nombre );

// 18. Write the uploaded file to the system
item.write( archivo );
if ( archivo.exists() ){
out.println( "GUARDADO " + archivo.getAbsolutePath() + "</p>");
}else{
// nunca se llega a ejecutar
out.println( "FALLO AL GUARDAR. NO EXISTE " + archivo.getAbsolutePath() + "</p>");
}

}
}
}

}catch( FileUploadException e ){
e.printStackTrace();
}catch (Exception e){
// poner respuesta = false; si existe alguna problema
e.printStackTrace();
}
}
out.println( "Fin de la operacion! ;)");
out.close();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

}


Agreue la siguiente configuración al archivo web.xml:

<servlet>
<servlet-name>UploadFile</servlet-name>
<servlet-class>servlets.UploadFile</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadFile</servlet-name>
<url-pattern>/UploadFile</url-pattern>
</servlet-mapping>
<context-param>
<param-name>dirUploadFiles</param-name>
<param-value>/public/images/avatar</param-value>
</context-param>
<context-param>
<param-name>maxFileSize</param-name>
<param-value>307200</param-value>
</context-param>


Testeando:

Figura 2: Procesamiento de la subida de un fichero al servidor

Notas finales:

  1. Si el tamaño del fichero subido excede los 300 Kb, parametro que hemos configurado dentro de web.xml con el nombre de maxFileSize, no se mostrará ningun mensaje en pantalla luego de que el Servlet proceso la petición de subir el fichero, esto es debido a que detro del bloque try/catch del Servlet UploadFile.java se lanza una excepción del tipo FileUploadBase.FileSizeLimitExceededException por el método parseRequest(), para poder mejorar este comportamiento deberiamos crear un método por ejemplo processFormFiled() que procese la subida de un fichero desde un formulario y que devuelva true/flase como respuesta.
  2. Se puede mejorar la presentación del procesamiento de la subida del fichero mediante un progress bar utilizando Ajax.
Download source code