Menú Curso Java Web (JSP's/Servlets) : Código Fuente Servlet InsertarServlet.java para insertar Información en Base de Datos.

(Anterior) Insertar información en Base de Datos através de un Servlet
Vea el CODIGO FUENTE del JSP exito.jsp
Vea el CODIGO FUENTE del JSP error.jsp

Código Fuente InsertarServlet.java

Debido a la longitud del Servlet, éste se encuentra dividido en cinco secciones seguido de una descripción para cada fragmento; a diferencia del JSP empleado para realizar búsquedas en Bases de Datos, este Servlet se encuentra más modularizado através de funciones para incrementar la legibilidad y su uso en aplicaciones de alto tráfico.

package com.osmosislatina.basesdedatos;

import javax.servlet.*; 
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
import java.util.*;

public class InsertarServlet extends HttpServlet { 

 

   protected IConexionPool pool;
   protected Connection conn;

   public void service(HttpServletRequest request, HttpServletResponse response) 
throws java.io.IOException, ServletException
    {

     // Sacar los  Datos de la Forma   
    String nombre = request.getParameter("nombre");
    String apellido = request.getParameter("apellido");
    String ciudad = request.getParameter("ciudad");
    String servicio = request.getParameter("servicio");
    String area = request.getParameter("area");
    String email = request.getParameter("email"); 

  • En la parte superior de este Servlet se importan tres tipos de librerías ("packages"): java.sql que representa las Clases para conectarse a Bases de Datos, java.util que contiene Clases utilitarias Java y com.osmosislatina.basesdedatos donde se encuentra un "Pool" para conectarse a Bases de Datos.

  • Se define la Clase(Servlet) InsertarServlet la cual hereda("inherit") el comportamiento de HttpServlet como lo hace cualquier otro Servlet, para posteriormente definir dos campos (pool y conn) que serán utilizados para definir la conexión hacia la Base de Datos así como su correspondiente "Pool".

  • El primer método declarado corresponde al principal de cualquier Servlet (service) que contiene los conocidos objetos de entrada HttpServletRequest y HttpServletResponse, donde inicialmente se extraen los datos introducidos por el usuario en la forma HTML através del objeto request.



    try { 
       
       // Verificar si existe usario por Correo Electrónico 
       
       String sql_busca = "select * CURSOJSP_ENCUESTA where email = ?";

       PreparedStatement statement = conn.prepareStatement(sql_busca);
       statement.setString(1,email);
       
       ResultSet result = statement.executeQuery();
       boolean rs = result.next();
       
       if (rs) 
	   { 
	       // Si existe el usario, rechazar
	       // Actualizar requisicion y llamar funcion de Rechazo 

       request.setAttribute("razonrechazo", "El correo electrónico proporcionado ya existe en la Base de Datos");
	       
	       rechazarInsertar(request,response);
	       
       } else { 
	       // No existe el usuario, actualizar requisicion
	       // Y llamar funcion para Insertar
	       
	       request.setAttribute("nombre",nombre);
	       request.setAttribute("apellido",apellido);
	       request.setAttribute("ciudad",ciudad);
	       request.setAttribute("servcio",servicio);
	       request.setAttribute("area",area);
	       request.setAttribute("email",email);

	       aceptarInsertar(request,response);

	   }
    }
	statement.close();
	result.close();
    catch (SQLException exc) 
    { 
	// Registrar posibles error en SQL hacia registros ("Logs") 
        // Actualizar requisicion y llamar funcion de Rechazo 

		getServletContext().log(" Ocurrio un error en la base de Datos mientras se intentaba insertar datos", exc);

                request.setAttribute("razonrechazo", "Ocurrio un error en la Base de Datos");
   
                rechazarInsertar(request,response);

    }

    } // TERMINA Método Service

La sección anterior describe la parte central del Servlet ya que contiene la lógica para aceptar o rechazar datos, sin embargo, son utilizados métodos específicos para llevar acabo inserciones o rechazos de información a diferencia del JSP utilizado para realizar búsquedas.

  • Se inicia un bloque try/catch que incluirá el proceso de búsqueda en la Base de Datos.

  • Se define una secuencia de búqueda para la Base de Datos con la intención de verificar que el correo electrónico proporcionado no exista; nótese que la secuencia contiene el carácter "?", dicho carácter será substituido por el dato proporcionado por el usuario.

  • Es generado un Objeto del tipo PreparedStatement, a diferencia de la Clase Statement mediante PreparedStatment es posible modificar parámetros de la secuencia SQL que cambian cada vez que sea producida una acción, esto permite que sea realizada una búsqueda en base al dato especifico proporcionado por el usuario; dicho Objeto es asociado con la conexión definida anteriormente, lo cual ocurre de la misma manera que la Clase Statement. El objeto conn que es asignado a PreparedStatement ya posee la conexión hacia la Base de Datos, la cual es realizada através del método init descrito posteriormente.

  • Através del método setString del Objeto statement es asociada la variable a la secuencia de búqueda SQL, los parámetros de este método indican la posición y valor asignado, donde la posición es representada por el carácter "?".

  • Se genera un Objeto del tipo ResultSet que representará los resultados de nuestra búsqueda; el inicio de la búsqueda es iniciado por medio del método executeQuery perteneciente a la Clase PreparedStatement.

  • Debido a que la búsqueda anterior retornará un renglón o un resultado nulo, se utiliza el método next() para verificar si existe el correo electrónico, si el resultado de next es verdadero esto indica que fue retornado un resultado, caso contrario (falso) indica un resultado nulo; el valor de este método (next()) es asignado a la variable rs.

  • Es declarada una condicional en base al resultado de la variable rs que indica la existencia del correo electrónico en la Base de Datos, si dicho correo existe ocurre lo siguiente:

    • Es colocado un atributo llamado razonrechazo en el Objeto request que contiene la razón por la que no fue posible continuar con el proceso.

    • Se invoca el método rechazarInsertar con los Objetos request y response (NOTA: El método rechazarInsertar se describe posteriormente.

    En caso de no existir el correo en la Base de Datos:

    • Son colocados los diversos valores proporcionados por el usuario en el objeto request.

    • Se invoca el método aceptarInsertar con los Objetos request y response (NOTA: El método aceptarInsertar se describe posteriormente.

  • Se invoca el método close de la Clases PreparedStatement y ResultSet para indicar el cierre de la búsqueda.

  • Terminada la condicional se define la sección catch del Bloque, la cual invoca el método rechazarInsertar en caso de ocurrir un error imprevisto.


    /** Redirecciona Errores a un Java Server Page **/

    public void rechazarInsertar(HttpServletRequest request, HttpServletResponse response) 
throws java.io.IOException, ServletException    {

	RequestDispatcher dispatch = getServletContext().getRequestDispatcher("/servidordatos/error.jsp");
    
	    dispatch.forward(request, response);

    }

El método rechazarInsertar definido anteriormente es invocado en caso de ocurrir cualquier tipo de error al momento de insertar datos, a continuación se describe:

  • Se genera un Objeto del tipo RequestDispatcher que toma como parámetro el JSP error.jsp.

  • Se invoca el método forward del Objeto dispatch que retorna el control hacia la página definida en el Objeto RequestDispatcher, en este caso el JSP error.jsp.


    /** Insertar Datos en la Base de Datos **/

    public void aceptarInsertar(HttpServletRequest request, HttpServletResponse response)
       throws java.io.IOException, ServletException 
    {

    try { 
	
       // Preparar linea para insertar informacion 
      String sql_inserta = "insert into CURSOJSP_ENCUESTA(nombre,apellido,ciudad,servicios,area,email) values ( ? , ? , ? , ? , ? , ?)";

       PreparedStatement statement = conn.prepareStatement(sql_inserta);
       statement.setString(1,(String) request.getAttribute("nombre"));
       statement.setString(2,(String) request.getAttribute("apellido"));
       statement.setString(3,(String) request.getAttribute("ciudad"));
       statement.setString(4,(String) request.getAttribute("servicio"));
       statement.setString(5,(String) request.getAttribute("area"));
       statement.setString(6,(String) request.getAttribute("email"));

       // Ejecutar Inserción de Datos 

       statement.executeUpdate();
       statement.close();

       // Enviar a Página de Exito 
	    
       RequestDispatcher dispatch = getServletContext().getRequestDispatcher("/servidordatos/exito.jsp");

    } catch (SQLException exc)    { 

	// Registrar posibles error en SQL hacia registros ("Logs") 
        // Actualizar requisición y llamar función de Rechazo 
	
     getServletContext().log(" Ocurrió un error en la base de Datos mientras se intentaba insertar datos", exc);

     request.setAttribute("razonrechazo", "ocurrió un error en la Base de Datos");
 
     rechazarInsertar(request,response);


    }

  }

El método aceptarInsertar es utilizado para llevar acabo la inserción en la Base de Datos, su funcionamiento es descrito en los siguientes incisos:

  • Se inicia un bloque try/catch que incluirá el proceso de inserción en la Base de datos.

  • Se define la secuencia de inserción para la Base de Datos; nótese que la secuencia contiene los caracteres "?", dichos caracteres serán substituidos por los datos proporcionado por el usuario.

  • Es generado un Objeto del tipo PreparedStatement, dicho Objeto es asociado con la conexión conn declarada como campo de la Clase y asignada en el método init del Servlet.

  • Através del método setString del Objeto statement son asociadas las variables a la secuencia de inserción, los parámetros de este método indican la posición y valor asignado, donde la posición es representada por el carácter "?".

  • Se invoca el método executeUpdate que inicia el proceso de inserción en la Base de Datos.

  • Se llama el método close de la Clase PreparedStatement para indicar el cierre de la inserción.

  • Y finalmente termina el bloque definiéndose un Objeto del tipo RequestDispatcher que redirecciona la solicitud hacia el JSP exito.jsp.

  • Dentro de la sección catch del Bloque es definida la lógica necesaria para invocar el método rechazarInsertar definido para procesar errores en la aplicación.

    /** Crear el Pool de Conexión en Clase de Arranque init **/

    public void init() { 

	// Traer el Contexto de la Aplicación y colocar Pool recién generado
	
	ServletContext application = getServletContext();
	pool = (IConexionPool) application.getAttribute("poolDeMysql");
	
	if (pool == null) { 
	    // No había pool/conexión en el contexto 
	    // Generar pool/conexión 
	    
	    try { 
		// Asegurarse que el "Driver" este disponible 
		Class.forName("com.mysql.jdbc.Driver").newInstance();
		
		// Crear el Pool de Conexión y guardarlo en el contexto de la Aplicación
		
		pool = new ConexionPoolBasico("jdbc:mysql://localhost:3306/cursojsp","web","osmosis");
	    
		conn = pool.extraerConexion();
		// Colocar conexión en el Contexto 
		application.setAttribute("poolDeMysql",pool);    
		
	    } catch (Exception exc) {
		
		// Registrar posibles error en Driver hacia registros ("Logs") 
		
		getServletContext().log("El \"Driver\" de la Base de Datos no se encontró u ocurrió un error al intentarse generar una conexión", exc);
		
	    }
	}
	
    }


    /** Cerrar Conexión y re-asignar al  Pool de Conexión 
        en Clase de finalización destroy **/

   public void destroy() { 
	
	try { 
	    
	    // Cerrar Conexión y Liberarla hacia Pool
	    pool.liberarConexion(conn); 
	    
	} catch (Exception exc) {
	    
	    // Registrar posibles error en Driver hacia registros ("Logs") 
	    // Actualizar requisición y llamar función de Rechazo 
	    
	    getServletContext().log("Error al liberar conexión", exc);
	    
	}
    }

    


Estos últimos métodos del Servlet son invocados al iniciarse y finalizarse la ejecución del método service, lo cual los hace idóneos para extraer y destruir una conexión hacia una Base de Datos.

  • En el método init primeramente se extrae el contexto de la aplicación y se revisa si existe un parámetro llamado poolDeMysql, este parámetro como su nombre lo indica representa el "Pool" de conexiones hacia la Base de Datos.

  • En caso que este parámetro sea nulo (no exista) se define un bloque try/catch para adquirir un "Pool" de conexiones, en este bloque primeramente se verifica la existencia de la Clase com.mysql.jdbc.Driver, esta Clase es la que permite la conexión hacia una Base de Datos Mysql.

  • Posteriormente se genera una instancia de la Clase principal del "Pool" ConexionPoolBasico, la cual toma como parámetros la información necesaria para conectarse a la Base de Datos Mysql y es asignada al campo pool definido al inicio del Servlet.

  • Una vez establecido el Objeto pool éste es colocado dentro del Contexto de la aplicación, lo cual permite que otros JSP's y Servlets tengan acceso al mismo "Pool" simplemente extrayéndolo del objeto application.

    Utilización de Contextos en Aplicación

    El colocar objetos/parámetros en el contexto de una aplicación tiene el mismo principio que emplear "Pool's" hacia Bases de Datos, que es justamente reutilizar y eficientizar el uso de recursos en un diseño con JSP's y Servlets.

    Al colocar un objeto en contexto se garantiza que éste se encuentre accesible a todos los usuarios de una aplicación, mientras el uso de sesiones permite guardar determinados datos para cada usuario que navegue determinada secuencia de JSP's o Servlets, mediante el contexto se puede compartir un recurso entre determinados usuarios.

    En este caso, el generar un "Pool" de conexiones para cada usuario que accese el Servlet puede ocasionar una severa carga sobre el servidor y por ende en el tiempo de respuesta de la aplicación, por esta razón se opta por extraer un "Pool" ya generado dentro del contexto.

    Finalmente vale mencionar que el colocar objetos dentro del contexto de una aplicación también puede ser de utilidad para otros objetos que sean compartidos entre diversos usuarios (sesiones) tales como un catalogo de productos o una lista de usuarios.

  • En el método destroy simplemente se define un bloque try/catch que invoca el método liberarConexion (perteneciente al "Pool" de conexión diseñado anteriormente) que se hace cargo liberar la conexión hacia la Base de Datos.

Terminos Legales de Contenido ©2000-2011 Osmosis Latina

Diseñado bajo estándares : XHTML   CSS  

webmaster@osmosislatina.com