07
May
10

Mi primera aplicación JSP

Bueno esta es mi primera aplicación JSP en ella se trata de reflejar el uso de:

  • llamado a clases con la directiva page
  • inclusión de paginas con la directiva include
  • inclusión de paginas con la etiqueta jsp:include
  • conectar a base de datos MySql con JSP
  • guardar datos en MySql con JSP
  • uso del objeto application
  • uso del objeto session
  • subir archivos con jsp api fileupload
  • convertir String a Date
  • transferencia de control con la etiqueta jsp:forward

la aplicación consta de 5 paginas en esta tratamos de hacer 2 de las cinco funciones básicas para un bean (Crear, Leer, Actualizar, Mostrar, Borrar).

la estructura del proyecto sería algo como así

la aplicación tiene 2 partes importantes registrar y listar, en la index.jsp ambas partes se integran en una sola vista.

index.jsp

<%@ page import="org.Model"%>
<html>
	<head>
		<title>TEST 01</title>
		<style type="text/css"><%@ include file="estilo.css"%></style>
		<!--En este ejercicio repasaremos por todas las funciones vistas anteriormente -->
	</head>
	<%
	Model model= (Model)application.getAttribute("model");
	if(model==null){
		model= new Model();
		model.setDriver("com.mysql.jdbc.Driver");
		model.setUrl("jdbc:mysql://localhost:3306/ejercicios");
		model.setNombre("root");
		model.setClave("");

		model.conectar();
		application.setAttribute("model",model);
	}
	%>
	<body>
		<table width="100%" border="0" cellspacing="0" cellpadding="5">
			<tr>
    			<td colspan="2" valign="top" align="right">
				  <div id="titulo" align="right"><img src="wallpaper.png" width="282" height="95"></div>
			    </td>
		  	</tr>
  			<tr>
    			<td valign="top">
					<jsp:include page="registro_empleado.jsp"/>
				</td>
    			<td>
					<div style="height:650px; overflow:scroll;">
						<jsp:include page="listar_empleado.jsp"/>
					</div>
				</td>
  			</tr>
		</table>
	</body>
</html>

en la siguiente pagina es solo el formulario donde se registran los empleados, noten el enctype debe ser multipart/form-data o multipart/mixed, para poder subir los archivos. en esta solamente se escribió el formulario (no head, ni body, ni el estilo).

registro_empleado.jsp

<form action="proceso.jsp" method="post" enctype="multipart/mixed">
	<table id="registro" width="110" border="0" cellspacing="0" cellpadding="5">
		<tr align="center">
			<td colspan="2" align="center">DATOS EMPLEADO</td>
		</tr>
		<tr>
			<td>Nombre</td>
			<td><input name="nombre" type="text"> </td>
		</tr>
		<tr>
			<td>Apellido</td>
			<td><input name="apellido" type="text"></td>
		</tr>
		<tr>
			<td>Identificacion</td>
			<td><input name="identificacion" type="text"></td>
		</tr>
		<tr>
			<td>Fecha de nacimiento</td>
    		<td><input name="fdn" type="text" value="dd/MM/yyyy"></td>
  		</tr>
  		<tr>
    		<td valign="top">Departamento</td>
    		<td>
				<input type="radio" name="departamento" value="1">Sitemas<br>
    			<input type="radio" name="departamento" value="2">Contabilidad<br>
				<input type="radio" name="departamento" value="3">Recursos humanos<br>
				<input type="radio" name="departamento" value="4">Administracion<br>
				<input type="radio" name="departamento" value="5">Servicios generales
	    	</td>
  		</tr>
  		<tr>
    		<td>Sueldo</td>
    		<td><input name="sueldo" type="text"></td>
  		</tr>
  		<tr>
    		<td>Auxilio de transporte</td>
    		<td><input name="transporte" type="text"></td>
  		</tr>
  		<tr>
    		<td>Foto</td>
    		<td><input name="foto" type="file"></td>
  		</tr>
  		<tr align="center">
    		<td colspan="2" align="center"><input type="submit" value="Guargar"></td>
  		</tr>
	</table>
</form>

en esta pagina se procesan los datos del formulario, se copian los campos del request al bean y la foto pasa al disco duro, se han dejado de importar paquetes con * y solamente las clases que se necesitan.

proceso.jsp

<%@ page import="java.util.List"%>
<%@ page import="org.apache.commons.fileupload.FileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.FileItem"%>
<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page import="java.io.File" %>

<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.text.DateFormat"%>
<%@ page import="java.text.SimpleDateFormat"%>

<%@ page import="org.Empleado"%>
<%@ page import="org.Model"%>

<%
   	/*FileItemFactory es una interfaz para crear FileItem*/
    FileItemFactory file_factory = new DiskFileItemFactory();

	/*ServletFileUpload esta clase convierte los input file a FileItem*/
    ServletFileUpload servlet_up = new ServletFileUpload(file_factory);
	/*sacando los FileItem del ServletFileUpload en una lista */
    List items = servlet_up.parseRequest(request);

	/*declaramos un hashmap donde guardaremos los parametros*/
	HashMap<String,String> parametros=new HashMap<String,String>();
    for(int i=0;i<items.size();i++){
		/*FileItem representa un archivo en memoria que puede ser pasado al disco duro*/
        FileItem item = (FileItem) items.get(i);
		/*item.isFormField() false=input file; true=text field*/
		String valor="";
        if (item.isFormField()){
			valor=item.getString();
        }else{
			/*creamos un nombre, para que no se sobbre-escriban archivos*/
			valor=(new Date().getTime())+item.getName();
			/*cual sera la ruta al archivo en el servidor*/
			File archivo_server = new File("c:/Archivos de programa/Apache Software Foundation/Apache Tomcat 6.0.24(stand)/webapps/ejercicio09/subidos/"+valor);
			/*y lo escribimos en el servido*/
			item.write(archivo_server);
		}
		/*guardamos los parametros dentro del hashmap*/
		parametros.put(item.getFieldName().toLowerCase(),valor);
	}
%>
<!--A este punto hemos copiado los archivos al disco duro del servidor -->
<!--y hemos guardado todos los parametros en el hashmap llamado parametros -->
<!--ahora sacaremos los datos para guardarlos en un objeto -->
<%
	DateFormat formato_fecha = new SimpleDateFormat("dd/MM/yyyy");
	/*utilizamos la DateFormat para convertir un string a Date*/
	Empleado empleado = new Empleado();
	empleado.setNombre(parametros.get("nombre"));
	empleado.setApellido(parametros.get("apellido"));
	empleado.setIdentificacion(Integer.parseInt(parametros.get("identificacion")));
	empleado.setDepartamento(parametros.get("departamento"));
	empleado.setSueldo(Double.parseDouble(parametros.get("sueldo")) );
	empleado.setTransporte(Double.parseDouble(parametros.get("transporte")));
	empleado.setFdn(formato_fecha.parse(parametros.get("fdn")));
	empleado.setFoto(parametros.get("foto"));
	Model model=(Model)application.getAttribute("model");
	model.agregarEmpleado(empleado);
%>
<!--La parte del hasmap lo quise poner de esa forma, pero cada quien es libre de -->
<!--hacerlo como mas le gusta mas adelante lo veran de forma bastante diferente -->
<jsp:forward page="index.jsp"/>

la lista de los empleados a su vez esta dividida en 2 una parte donde se hace la lista y la otra donde específicamente se muestra un empleado.

en la primera de estas, se rescatan los datos de la base de datos, se recorren y guarda cada empleado en la session y luego se llama a la pagina que los muestra

listar_empleado.jsp

<%@ page import="java.util.List"%>

<%@ page import="org.Empleado"%>
<%@ page import="org.Model"%>
	<%
		Model model=(Model)application.getAttribute("model");
		List lista_empleado=model.listaEmpleado();
		Double total_sueldo=0.0;
		Double total_auxili=0.0;
	 %>
		<table border="1" cellspacing="0" cellpadding="5">
			<tr><td colspan="2" align="center" >DATOS NOMINA </td></tr>
  				<%for(int i=0;i<lista_empleado.size();i++){
					Empleado empleado=(Empleado)lista_empleado.get(i);

					total_sueldo=total_sueldo+empleado.getSueldo();
					total_auxili=total_auxili+empleado.getTransporte();
					session.setAttribute("empleado",empleado);
			%>
			<tr>
				<jsp:include page="ver_empleado.jsp"/>
			</tr>
		<%}%>
			<tr><td>TOTAL SUELDO</td> <td><%=total_sueldo%></td> </tr>
			<tr><td>TOTAL AUXILIO</td> <td><%=total_auxili%></td> </tr>
			<tr><td>TOTAL NOMINA</td> <td><%=total_sueldo+total_auxili%></td> </tr>
		</table>
	</body>
</html>

en la pagina siguiente se trae un empleado que esta guardado en la session y se muestran los datos de este en la pagina

ver_empleado.jsp

<%@ page import="org.Empleado"%>
<%@ page import="java.util.Date"%>

<%
Empleado empleado=(Empleado)session.getAttribute("empleado");
int edad= new Date().getYear() - empleado.getFdn().getYear();
String departamento="";
if(empleado.getDepartamento().matches("1")){departamento="Sitemas";}
if(empleado.getDepartamento().matches("2")){departamento="Contabilidad";}
if(empleado.getDepartamento().matches("3")){departamento="Recursos humanos";}
if(empleado.getDepartamento().matches("4")){departamento="Administracion";}
if(empleado.getDepartamento().matches("5")){departamento="Servicios generales";}
%>
<td>
	<img  width="150" height="200" src="subidos/<%=empleado.getFoto()%>"/>
</td>
<td>
	<table width="100%" border="0" cellspacing="0" cellpadding="1">
		<tr><td>ID</td><td><%=empleado.getId()%></td></tr>
		<tr>
  			<td>NOMBRE</td><td><%=empleado.getNombre()+" "+empleado.getApellido()%></td>
		</tr>
		<tr>
  			<td>IDENTIFICACION</td><td><%=empleado.getIdentificacion()%></td>
		</tr>
		<tr>
   			<td>DEPARTAMENTO</td><td><%=departamento%></td>
		</tr>
		<tr>
    		<td>SUELDO</td><td><%=empleado.getSueldo()%></td>
  		</tr>
		<tr>
    		<td>AUXILIO</td><td><%=empleado.getTransporte()%></td>
  		</tr>
		<tr>
    		<td>TOTAL DEVENGADO</td><td><%=empleado.getTransporte()+empleado.getSueldo()%></td>
  		</tr>
	</table>
</td>

en la aplicación utilizamos el siguiente estilo, no soy diseñador y con poco tiempo para programar, no encontré una plantilla así que no la critiquen

estilo.css

*{color:#CC0000;}
body{background-color: #F0F0F0;}
table#registro{font-weight:bold;}
div#titulo{
	background-color: #B00000;
	color: #B00000;
	background:#B00000;
}

y la siguiente base de datos

ejercicios

CREATE DATABASE IF NOT EXISTS `ejercicios` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `ejercicios`;

# Dumping structure for table ejercicios.empleado
CREATE TABLE IF NOT EXISTS `empleado` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `nombre` varchar(100) NOT NULL DEFAULT '',
  `apellido` varchar(100) NOT NULL DEFAULT '',
  `identificacion` int(20) NOT NULL DEFAULT '0',
  `departamento` varchar(100) NOT NULL DEFAULT '',
  `sueldo` double NOT NULL DEFAULT '0',
  `transporte` double NOT NULL DEFAULT '0',
  `fdn` date NOT NULL DEFAULT '2010-01-01',
  `foto` varchar(100) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

# Dumping data for table ejercicios.empleado: 4 rows
/*!40000 ALTER TABLE `empleado` DISABLE KEYS */;
INSERT INTO `empleado` (`id`, `nombre`, `apellido`, `identificacion`, `departamento`, `sueldo`, `transporte`, `fdn`, `foto`) VALUES (1, 'Mauro Cesar', 'Gomez Mejia', 1045465123, '1', 850000, 50000, '1986-07-12', '1273120244484avartaryahoo.bmp');

INSERT INTO `empleado` (`id`, `nombre`, `apellido`, `identificacion`, `departamento`, `sueldo`, `transporte`, `fdn`, `foto`) VALUES (2, 'Sandra Patricia', 'Pinedo Florez', 1562153142, '2', 850000, 50000, '1983-03-02', '1273120579281Dibujo.bmp');

INSERT INTO `empleado` (`id`, `nombre`, `apellido`, `identificacion`, `departamento`, `sueldo`, `transporte`, `fdn`, `foto`) VALUES (3, 'Cesar Augusto', 'Anaya Boorguez', 1225456345, '4', 850000, 50000, '1975-08-21', '1273121305343images.jpg');

INSERT INTO `empleado` (`id`, `nombre`, `apellido`, `identificacion`, `departamento`, `sueldo`, `transporte`, `fdn`, `foto`) VALUES (4, 'Javier Andres', 'Ibarra Lopez', 1045124563, '1', 950000, 50000, '1979-09-17', '1273206286625F200811201452292577871692.jpg');

recursos usados:
commons.fileupload

commons.io

conector-mysql


30 Responses to “Mi primera aplicación JSP”


  1. 1 Griselda
    mayo 14, 2010 a las 8:22 pm

    AYUDAME :
    CREE UNA PAGINA WEB EN MY ECLIPSE
    YA TENGO EL DOMINIO YE EL HOSTING
    PERO NOSE COMO LEVANTARLA ESTOY UTILIZANDO FILZILA

  2. 2 Geis Garcia
    agosto 6, 2010 a las 1:27 pm

    Excelente tuto men esa aplicasion era lo que me estaba imaginando la monte con netbean y glasfish corre al pelo

    una pregunta alli en la pagina aparece un numero de celular parece ser tigo se te puede llamar

    • agosto 7, 2010 a las 8:12 am

      claro que puedes llamar

  3. 4 Daniel
    noviembre 23, 2010 a las 1:57 am

    Excelente hermano…me cayo como anillo al dedo….muchas Gracias….XD

  4. 5 Josema
    enero 31, 2011 a las 7:00 am

    Muy bien el tutorial pero donde podría conseguir las clases Empleado y Model para completarlo?

    • enero 31, 2011 a las 8:01 am

      en el descargable esta completo

  5. 7 enrique
    mayo 3, 2011 a las 12:02 am

    mm y cual es la que corre por que abro con explorer el index y no lo habre

    • mayo 11, 2011 a las 7:25 am

      porque no se ejecutan en un browser, se suben a un servidor de aplicaciones o a un contenedor de servlets JBoss, GlassFish, Tomcat… etc.

  6. 9 Markximo
    junio 2, 2011 a las 4:57 pm

    Que tal ingenioDS

    Oye muy buen tutorial lo estoy siguiendo en la parte de subir archivo, lo he casi implementado en mi aplicacion pero, me manda un error al momento de insertar en la base de datos ya que si solo le pongo el enctype multipart/form-data no me manda los valores a insertar y si le pongo el multipart/mixed, no reconoce los parametros de tipo input text es decir me los manda null, estoy trabajando con la JDK 1.4 en Myeclipse. Te agradezco de antemano la ayuda.

    Saludos

    • junio 3, 2011 a las 8:07 am

      en la pagina donde aparece lo de subir archivos hay un comentario de como hacer casting a todos los campos para no tener problemas con eso, ademas en uno donde aplique MVC uso los 2 tipos, así que hay tienes por donde seguirte

      • 11 Markximo
        junio 9, 2011 a las 1:09 pm

        Que tal después de batallar un rato aquí esta la solución. Pongo mi código y espero les sirva a usuarios que han tenido problemas con esto, al final fue un pequeño error pero, bueno. Muchas gracias a todos por la ayuda.

        /*Iniciamos la parte para insertar el archivo sobre el servidor*/
        ServletFileUpload SFileUpload = new ServletFileUpload(new DiskFileItemFactory());
        Hashtable Parameters = new Hashtable();

        List items = SFileUpload.parseRequest(request);
        for(int i=0;i<items.size();i++){
        /*FileItem representa un archivo en memoria que puede ser pasado al disco duro*/
        FileItem item = (FileItem) items.get(i);
        /*item.isFormField() false=input file; true=text field*/
        String valor="";
        if (item.isFormField()){
        valor=item.getString();
        Parameters.put(item.getFieldName(), item.getString()); //<———– para meter todos los datos en el hashmap
        }else{

        String n[] =item.getName().replace("\\","-").split("-"); //<———– para obtener un nombre distinto del archivo
        String nombreReal=n[n.length-1]; //nombre real del archivo para guardar
        valor=(new Date().getTime())+nombreReal;
        /*creamos un nombre, para que no se sobbre-escriban archivos*/
        //valor=(new Date().getTime())+item.getName();
        /*cual sera la ruta al archivo en el servidor*/
        out.println("Entro a insertar el archivo!”);
        File archivo_server = new File(“c:/subidos/”+valor);
        /*y lo escribimos en el servido*/
        item.write(archivo_server);
        valorStrg = valor ;
        }
        /*guardamos los parametros dentro del hashmap*/
        Parameters.put(item.getFieldName().toLowerCase(),valor);
        }

        /*Cerramos la parte para la carga de archivos*/

        if(ServletFileUpload.isMultipartContent(request)){

        Iterator iter = null;

        //if((String)Parameters.get(“bCargar”)!=null){
        try{

        // Aqui recuperamos todos los valores que fueron introducidos en el hashmap y los asignamos a variables para que puedan ser trabajados

        accion = (String)Parameters.get(“hdAccion”);
        cveTEMM = (String)Parameters.get(“cveTEMM”);
        cmbEdificio = (String)Parameters.get(“cmbEdificio”);

        numSerie = (String)Parameters.get(“numSerie”);
        descEquipo = (String)Parameters.get(“descEquipo”);
        cmbEquipo = (String)Parameters.get(“cmbEquipo”);
        txtFechaFabricacion = (String)Parameters.get(“txtFechaFabricacion”);
        txtFechaInstalacion = (String)Parameters.get(“txtFechaInstalacion”);
        periodoMatto = (String)Parameters.get(“periodoMatto”);
        ultimoMatto = (String)Parameters.get(“ultimoMatto”);
        ultimaFalla = (String)Parameters.get(“ultimaFalla”);
        txtFechaSustitucion = (String)Parameters.get(“txtFechaSustitucion”);
        activo = (String)Parameters.get(“activo”);
        costoEquipo = (String)Parameters.get(“costoEquipo”);
        tipoMoneda = (String)Parameters.get(“tipoMoneda”);
        costoInstalacion = (String)Parameters.get(“costoInstalacion”);
        tipoMonedaIns = (String)Parameters.get(“tipoMonedaIns”);
        cmbProveedor = (String)Parameters.get(“cmbProveedor”);
        capacidadActual = (String)Parameters.get(“capacidadActual”);
        redundanteDe = (String)Parameters.get(“redundanteDe”);
        posicionArea = (String)Parameters.get(“posicionArea”);
        txtFechaCompra = (String)Parameters.get(“txtFechaCompra”);
        txtFechaUltimoMatto = (String)Parameters.get(“txtFechaUltimoMatto”);

        InputStream isFoto = (InputStream)Parameters.get(“fFoto”);
        String sResumen = (String)Parameters.get(“fResumen”);

        out.println(“Inserción Exitosa!”);

        }

        catch (Exception e) { out.println(e.toString()); }
        finally {

        }
        }

        /*Finalizamos la parte de subir archivo*/

  7. 12 jose
    septiembre 9, 2011 a las 2:03 am

    COmo puedo abrir ese proyectto en Netbeans para correrlo en mi pc ?
    Epsero que me puedas ayudar gracias.

    • septiembre 9, 2011 a las 9:02 am

      Para abrir en ¿netbeans?… ¿que es netbeans?… la verdad si se que es, pero no se puede abrir lo que si puedes es crear una aplicación web en netbeans y agregar los src al proyecto recién creado en netbeans.

      • 14 Daniel
        octubre 11, 2011 a las 12:19 pm

        Oye, el programa marca un error HTTP: 500 en la linea 23 de tu codigo…

      • octubre 11, 2011 a las 12:39 pm

        en la linea 23 de que pagina o clase?

      • 16 Daniel
        octubre 11, 2011 a las 12:54 pm

        de la clase proceso

      • octubre 11, 2011 a las 1:37 pm

        Revisaré en cuanto pueda, pero es raro porque a varias persona les ha funcionado correctamente.

      • 18 Daniel
        octubre 12, 2011 a las 8:20 am

        Ya cheque el error. La contraseña de mysql que yo tengo no coincide con la que tiene la clase Model.java
        Una pregunta ¿Cómo generaste el .class si ninguna de las dos clases tiene un metodo main?
        Mira la contraseña de mysql que yo tengo es: n0m3l0s3
        como puedo generar estos .class de las clases????

  8. 19 Adrian
    mayo 3, 2012 a las 10:44 am

    HOLA oie muy buen tuto… PERO TENGO UN PEQUEÑO problema… CUANDO ESTOY cargando datos aparace en seguida el error 500 y no m deja introducir los datos: mira este es el error:

    excepción

    org.apache.jasper.JasperException: Ha sucedido una excepción al procesar la página JSP /proceso.jsp en línea 23

    20: /*ServletFileUpload esta clase convierte los input file a FileItem*/
    21: ServletFileUpload servlet_up = new ServletFileUpload(file_factory);
    22: /*sacando los FileItem del ServletFileUpload en una lista */
    23: List items = servlet_up.parseRequest(request); /<———– dice k el error vienen de aquí!!!
    24:
    25: /*declaramos un hashmap donde guardaremos los parametros*/
    26: HashMap parametros=new HashMap();

    Y ya trate de reparar pero nada!!! PUEDES AYUDARME??

    • mayo 4, 2012 a las 8:51 am

      mañana a las 2pm voy a estar conectado al msn si quieres revisamos eso mañana, a varias personas les ha salido ese error a otros no, así es un caso al que hay que revisar

      • noviembre 16, 2012 a las 12:36 am

        Podrias decirme por fa como arreglo eso… de antemano… gracias

      • noviembre 21, 2012 a las 3:34 pm

        Lo que sucede es el ENCTYPE de la etiqueta form dependiendo de la configuración debes usar

        o

  9. 23 Adrian
    mayo 3, 2012 a las 11:27 am

    ya lei todo este blog y nada k puedo encontrar como solucion

    • 24 poncho
      octubre 16, 2012 a las 12:23 pm

      que tal…buen aporte…el link de tus archivos ya no esta vigente!! o no puedo descargarlos…. podrias enviarlo a mi correo…

      de antemano muchas gracias!!!

      • 25 poncho
        octubre 25, 2012 a las 12:24 pm

        holaaaaaaa necesito ayuda please!…los enlaces para descargar ya no sirven!!!…

      • octubre 25, 2012 a las 1:48 pm

        http://sdrv.ms/Nn3o4N en esa ruta están los códigos

  10. enero 29, 2013 a las 12:35 pm

    Hola encontraon la solucion en la linea 23 de proceso.jsp? Gracias

    • enero 29, 2013 a las 2:09 pm

      el problema es el ENCTYPE dependiendo de la configuración toma un valor aquí hay una explicación completa de este atributo http://www.w3schools.com/tags/att_form_enctype.asp

  11. 29 luiz
    mayo 8, 2013 a las 1:42 am

    señor mis respetos, gracias por compartirnos el material me funciono al 100


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s


I+Ds

Dudas consultas
Facebook
Twiter
Google +

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevas publicaciones por correo.

Únete a otros 348 seguidores

Ingenio DS en Facebook

Redes Sociales y Archivos

Entradas

mayo 2010
L M X J V S D
« Abr   Jun »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

IngenioDS en twiter


A %d blogueros les gusta esto: