1. Tutorial de la Aplicación
1.1. Creacion de un Nuevo Proyecto en Eclipse
Indicaciones:
- Project Name: AppDataStoreJDO. Puedes cambiar el nombre del proyecto por el que más te guste.
- Package: com.gae.app. Puedes cambiar el nombre del paquete si deseas.
- Quitar el "check" en la opción que dice "Use Google Web Toolkit"
- Click en "Finish"
1.2. Creando la Clase Empleado
La clase "Empleado" que va a ser la clase encargada de manejar la persistencia de datos.Indicaciones:
- Crear un nuevo paquete con el siguiente nombre: com.gae.app.bean
- Dentro del paquete "com.gae.app.bean" crear una clase con el siguiente nombre: Empleado
package com.gae.app.bean; import java.util.Date; import javax.jdo.annotations.*; import com.google.appengine.api.users.User; //Especifica que la clase es Persistente @PersistenceCapable(identityType=IdentityType.APPLICATION) public class Empleado { //Va a ser la clave primaria de la clase Empleado @PrimaryKey //Para que genere el codigo de forma automatica @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) private Long id; @Persistent private User user; @Persistent private String userid; @Persistent private String nombres; @Persistent private String apellidos; @Persistent private String dni; @Persistent private String sexo; @Persistent private Date fechanac; @Persistent private Date fechareg; //Constructor de la Clase public Empleado (User user, String userid, String nombres, String apellidos, String dni, String sexo, Date fechanac, Date fechareg) { this.user=user; this.userid=userid; this.nombres=nombres; this.apellidos=apellidos; this.dni=dni; this.sexo=sexo; this.fechanac=fechanac; this.fechareg=fechareg; } //Metodos get y set public Long getId() { return id; } public void setId(Long id) { this.id = id; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String getUserid() { return userid; } public void setUserid(String userid) { this.userid = userid; } public String getNombres() { return nombres; } public void setNombres(String nombres) { this.nombres = nombres; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public String getDni() { return dni; } public void setDni(String dni) { this.dni = dni; } public String getSexo() { return sexo; } public void setSexo(String sexo) { this.sexo = sexo; } public Date getFechanac() { return fechanac; } public void setFechanac(Date fechanac) { this.fechanac = fechanac; } public Date getFechareg() { return fechareg; } public void setFechareg(Date fechareg) { this.fechareg = fechareg; } }
1.3. Creando la Clase PMF
La clase "PMF" va a tener la variable encargada de controlar las peticiones de registros y búsqueda de la información almacenada.Indicaciones:
- Crear un nuevo paquete con el siguiente nombre: com.gae.app.dao
- Dentro del paquete "com.gae.app.dao" crear una clase con el siguiente nombre: PMF
package com.gae.app.dao; import javax.jdo.JDOHelper; import javax.jdo.PersistenceManagerFactory; public final class PMF { //Variable encargada de controlar las peticiones private static final PersistenceManagerFactory pmfInstancia=JDOHelper.getPersistenceManagerFactory("transactions-optional"); //Para que no puedan instanciar la clase private PMF(){} //Retorna la instancia encargada de controlar las peticiones public static PersistenceManagerFactory get(){ return pmfInstancia; } }
1.4. Creando la Clase EmpleadoDao
La clase "EmpleadoDao" va a tener los métodos para insertar, actualizar, eliminar y/o consultar datos persistentes utilizando JDO(Java Data Objects) y como Query Language a JDOQL .Indicaciones:
- Dentro del paquete "com.gae.app.dao" crear una clase con el siguiente nombre: EmpleadoDao
Ingresar el siguiente código dentro de la clase EmpleadoDao :
package com.gae.app.dao; import javax.jdo.PersistenceManager; import com.gae.app.bean.Empleado; import java.util.*; import com.google.appengine.api.users.*; import javax.jdo.Query; public class EmpleadoDao { //Metodo para Insertar un Nuevo Registro public static void insertarEmpleado (User user,String userid,String nombres,String apellidos,String dni, String sexo, Date fechanac, Date fechareg) { //LLamamos a la clase que tendra la persistencia PersistenceManager pm = PMF.get().getPersistenceManager(); // Nueva variable empleado Empleado empleado=new Empleado(user,userid,nombres,apellidos,dni,sexo, fechanac,fechareg); //Haciendo la persistencia de datos pm.makePersistent(empleado); } @SuppressWarnings("unchecked") //Metodo para Listar Empleados public static List<Empleado> listarEmpleados(){ PersistenceManager pm = PMF.get().getPersistenceManager(); Query query = pm.newQuery("select from "+Empleado.class.getName()+""); return (List<Empleado>) query.execute(); } }
1.5. Clase AppDataStoreJDOServlet
Después de realizar los pasos anteriores, proseguiremos a configurar el servlet para procesar las solicitudes y respuestas.Ingresar el siguiente código fuente dentro del servlet:
package com.gae.app; import com.gae.app.dao.*; import com.gae.app.bean.*; import java.util.*; import java.io.IOException; import java.text.ParseException; import java.text.SimpleDateFormat; import javax.servlet.*; import javax.servlet.http.*; import com.google.appengine.api.users.*; @SuppressWarnings("serial") public class AppDataStoreJDOServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if(req.getParameter("action").equals("registrar")){ UserService userService= UserServiceFactory.getUserService(); User user=userService.getCurrentUser(); String userid=user.getUserId(); Date fechareg = new Date(); Date fechanac = new Date(); String nombres=req.getParameter("nombres"); String apellidos=req.getParameter("apellidos"); String dni=req.getParameter("dni"); String sexo=req.getParameter("sexo"); try { SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); fechanac = sdf.parse(req.getParameter("fechanac")); } catch (ParseException e) { System.out.println("Excepcion:" + e); } EmpleadoDao.insertarEmpleado(user,userid,nombres,apellidos,dni,sexo,fechanac,fechareg); List<Empleado> empleados = EmpleadoDao.listarEmpleados(); req.setAttribute("empleados", empleados); RequestDispatcher rd = getServletContext().getRequestDispatcher("/ListarEmpleados.jsp"); rd.forward(req, resp); } } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if(req.getParameter("action").equals("listarEmpleados")){ List<Empleado> empleados=EmpleadoDao.listarEmpleados(); req.setAttribute("empleados", empleados); RequestDispatcher rd = getServletContext().getRequestDispatcher("/ListarEmpleados.jsp"); rd.forward(req, resp); } } }
1.6. Creando la Páginas JSP
1.6.1. index.jsp
Esta página contendrá el formulario de registro de un nuevo empleado previamente a un login de acceso(Cuenta en Gmail).Ingresar el siguiente código en la página index.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ page import="java.util.*"%> <%@ page import="java.text.SimpleDateFormat" %> <%@ page import="com.google.appengine.api.users.User" %> <%@ page import="com.google.appengine.api.users.UserService" %> <%@ page import="com.google.appengine.api.users.UserServiceFactory" %> <html> <head> <title>Mantenimiento de Empleados</title> <link rel="stylesheet" type="text/css" href="css/estilos.css" /> </head> <body> <% UserService userService = UserServiceFactory.getUserService(); //Capturamos al Usuario Actual User user = userService.getCurrentUser(); if (user != null) { %> <p align="center"><<Bienvenido, <%= user.getNickname() %>>> <a href="<%= userService.createLogoutURL(request.getRequestURI()) %>">Cerrar Sesion</a> <a href="/empleado?action=listarEmpleados">Listar Empleados</a> </p> <form action="/empleado" method="post"> <div align="center"> <table border="0" cellspacing="1" cellpadding="5"> <tr bgcolor="#4B4B5A" style="color: white;" ><td colspan="2" align="center"><h3><u>Mantenimiento de Empleados</u></h3></td></tr> <tr> <td>Nombres:</td> <td><input type="text" name="nombres" /></td> </tr> <tr> <td>Apellidos:</td> <td><input type="text" name="apellidos" /></td> </tr> <tr> <td>DNI:</td> <td><input type="text" name="dni" /> </td> </tr> <tr> <td>Sexo:</td> <td><select name="sexo"> <option value="-" selected> -- Seleccionar --</option> <option value="M" >Masculino</option> <option value="F">Femenino</option> </select> </td> </tr> <tr> <td>Fecha de Nacimiento:</td> <td><input type="text" name="fechanac" />(dia/mes/anio) </td> </tr> <tr> <td colspan="2" align="center"> <input type="hidden" name="action" value="registrar"/> <input type="submit" value="Registrar" class="boton" > </td> </tr> </table> </div> </form> <% } else { %> <p>DEBE INICIAR SESION ... click <a href="<%= userService.createLoginURL(request.getRequestURI()) %>">AQUI</a> para loguearse.</p> <% } %> </body> </html>
1.6.2. ListarEmpleados.jsp
Esta página contendrá un listado de todos los registros de los empleado que hagan los usuarios(logueados).Ingresar el siguiente código en la página ListarEmpleados.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@page import="com.gae.app.*"%> <%@page import="com.gae.app.bean.*"%> <%@page import="com.gae.app.dao.*"%> <%@page import="java.util.*"%> <%@page import="java.text.SimpleDateFormat" %> <% List<Empleado> empleados =(List<Empleado>)request.getAttribute("empleados"); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); %> <html> <head> <title>Listar Empleados</title> <link rel="stylesheet" type="text/css" href="css/estilos.css" /> </head> <body> <% if (empleados.size() > 0) { %> <div align="center"> <table border="0" cellspacing="1" cellpadding="5" bgcolor="#CCCCCC"> <tr><td colspan="6" align="center" ><%= empleados.size() %> resultados encontrados ::::: </td></tr> <tr align="center" class="cabeceraTable"> <td><b>#</b></td> <td><b>Nombres</b></td> <td><b>Apellidos</b></td> <td><b>DNI</b></td> <td><b>Sexo</b></td> <td><b>Fecha de Nacimiento</b></td> </tr> <% int n=1; %> <% for (int i = 0;i<empleados.size();i++) { %> <% Empleado e = (Empleado)empleados.get(i); %> <tr style="background:#ffffff" onMouseOver="this.style.background='#eeeeee';" onMouseOut="this.style.background='#ffffff';"> <td><%= n++%></td> <td><%= e.getNombres() %></td> <td><%= e.getApellidos()%></td> <td align="center"><%= e.getDni() %></td> <td align="center"><%= e.getSexo() %></td> <td align="center"><%= sdf.format(e.getFechanac())%></td> </tr> <% } %> </table> <% } else { %> <table> <tr><td>Ningun resultado. </td></tr> </table></div> <% } %> </body> </html>
estilos.css
body { font:12px "Lucida Grande", "Lucida Sans", "Trebuchet MS",verdana, sans-serif; color:#4B4B5A; } table { font:12px "Lucida Grande", "Lucida Sans", "Trebuchet MS",verdana, sans-serif; border:1px solid #4B4B5A; color: #4B4B5A; font-weight: bold; } .boton{ background-color:#4B4B5A; font:11px "Lucida Grande", "Lucida Sans", "Trebuchet MS",verdana, sans-serif; color:white; } .cabeceraTable{ background-color:#4B4B5A; font:11px "Lucida Grande", "Lucida Sans", "Trebuchet MS",verdana, sans-serif; color:white; }
1.7. Archivo web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>empleado</servlet-name> <servlet-class>com.gae.app.AppDataStoreJDOServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>empleado</servlet-name> <url-pattern>/empleado</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
1.8. Archivo jdoconfig.xml
Dejar el archivo por defecto tal y como se muestra a continuación:<?xml version="1.0" encoding="utf-8"?> <jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig"> <persistence-manager-factory name="transactions-optional"> <property name="javax.jdo.PersistenceManagerFactoryClass" value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/> <property name="javax.jdo.option.ConnectionURL" value="appengine"/> <property name="javax.jdo.option.NontransactionalRead" value="true"/> <property name="javax.jdo.option.NontransactionalWrite" value="true"/> <property name="javax.jdo.option.RetainValues" value="true"/> <property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/> </persistence-manager-factory> </jdoconfig>
5 comentarios:
Enhorabuena Trujillo, una explicación muy clara y detallada, me ha venido magnífico para estudiar la estructura y con los códigos fuentes empezar a analizar el JDO.
Te agradezco este tutorial y espero que en breve adiciones borrar registros y más formas de utilización del DataStore con sus transacciones.
NO he encontrado nada en Internet tan sumamente bien explicado.
Por otro lado al hacer Deploy para subir la aplicación y así testearla, me da el siguiente error:
Unable to update:
com.google.appengine.tools.admin.JspCompilationException: Failed to compile jsp files.
at com.google.appengine.tools.admin.Application.compileJsps(Application.java:456)
at com.google.appengine.tools.admin.Application.createStagingDirectory(Application.java:334)
at com.google.appengine.tools.admin.AppAdminImpl.doUpdate(AppAdminImpl.java:282)
at com.google.appengine.tools.admin.AppAdminImpl.update(AppAdminImpl.java:48)
at com.google.appengine.eclipse.core.proxy.AppEngineBridgeImpl.deploy(AppEngineBridgeImpl.java:265)
at com.google.appengine.eclipse.core.deploy.DeployProjectJob.runInWorkspace(DeployProjectJob.java:144)
at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:38)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Sabes el motivo por el cual no funciona en el appspot? Gracias
excelente informacion
todo muy detallado y de facil comprension, esta muy bueno
hola, he estado visitando tu pagina y tienes contenido muy interesante, sigue posteando asi, me encantará volver, saludos!
Publicar un comentario