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

(Anterior) Actualizar información en Base de Datos a través de Servlets
Vea el CODIGO FUENTE del Servlet ConfirmarActualizarServlet.java

Código Fuente ActualizarServlet.java

Debido a la longitud del Servlet, éste se encuentra dividido en cuatro secciones seguido de una descripción para cada fragmento.

package com.osmosislatina.basesdedatos;

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


public class ActualizarServlet extends HttpServlet { 

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

     // Sacar los  Datos de la Forma   
    String id = request.getParameter("id");

    // Declarar Conexión y DataSource hacia Base de Datos          
    DataSource dataSource =  null;
    Connection conn = null;

  • En la parte superior de este Servlet como cualquier otra Clase Java se importan las librerías ("packages") que serán utilizadas : java.sql que representa las Clases para conectarse a Bases de Datos, java.util que contiene Clases utilitarias Java, javax.sql que contiene las implementaciones más recientes para Bases de Datos (DataSource) y javax.naming que proporciona las Clases para localizar recursos vía JNDI ("Java Naming Directory Interface").

  • Se define la Clase(Servlet) ActualizarServlet la cual hereda("inherit") el comportamiento de HttpServlet como lo hace cualquier otro Servlet; de la misma manera se declara el método principal del Servlet (service) que contiene los conocidos objetos de entrada HttpServletRequest y HttpServletResponse.

  • Como primer paso dentro del método service se extraen los datos introducidos por el usuario en la forma HTML a través del objeto request y seguido se definen dos variables para asignar la conexión (Connection) y recurso (DataSource) hacia la Base de Datos.


    // Conectarse a la Base de Datos 

    try { 
       
    // Traer el Contexto JNDI
       Context initContext = new InitialContext();
       Context ctx  = (Context)initContext.lookup("java:/comp/env");



      // BLOQUE try/catch/finally continua

La sección anterior describe la parte central del Servlet ya que contiene la lógica para buscar el usuario (id) que será actualizado.

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

  • Primeramente es generado un objeto de Contexto Inicial JNDI en el cual se realiza una búqueda vía el método lookup sobre java:/comp/env. El parámetro java:/comp/env representa la ruta base donde son colocados todos los recursos JNDI en un ambiente J2EE, dicho valor es definido de esta manera en la misma especificación J2EE. (NOTA: Este contexto no es lo mismo que el contexto de un Servlet utilizado en ejemplos anteriores).

  • Una vez definido y encontrado el contexto inicial JNDI, se realiza otra búsqueda sobre esta ruta base intentando ubicar el recurso jdbc/ConexionMySQL, dicho recurso es asignado a la variable dataSource que representará nuestra Base de Datos.

  • Posteriormente a través del método getConnection de la Clase DataSource se genera una conexión hacia la Base de Datos la cual es asignada a la variable conn.

java:/comp/env/jdbc/ConexionMySQL = Base de Datos

Mediante JNDI es posible definir recursos como conexiones hacia Bases de Datos a un nivel global de "Servlet Engine"/"Application Server", evitando así la escritura de código extenso y administrativo, sin embargo, también es necesario definir sus características en archivos de configuración.

WAR("Web-Archive")

En el archivo web.xml de cada aplicación (WAR-"Web-Archive") es el primer lugar donde debe definirse el recurso JNDI para que todos sus JSP's y Servlets tengan acceso al recurso :

 
 <resource-ref>
      <description>Conexión hacia Base de Datos SQL</description>
      <res-ref-name>jdbc/ConexionMySQL</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
 </resource-ref>

"Servlet Engine"/"Application Server"

Además del WAR ("Web-Archive") también es necesario definir el recurso al nivel de "Servlet Engine"/"Application Server" ya que es aquí donde serán definidos los parámetros físicos (URL de Conexión) y características del recurso.

Para Tomcat que es el "Servlet Engine" empleado en este curso, la configuración debe ser realizada en el archivo server.xml residente en $TOMCAT_HOME/conf/ , donde $TOMCAT_HOME es el directorio de instalación de Tomcat.

La configuración es descrita a continuación :

NOTA: La configuración en otros "Servlet Engines"/"Application Servers" puede variar substancialmente de la que es descrita a continuación.

 
       <Context path="" docBase="cursojsp" debug="0">

         <Resource name="jdbc/ConexionMySQL"
               auth="Container"
               type="javax.sql.DataSource"/>
         
         <ResourceParams name="jdbc/ConexionMySQL">
   
            <parameter>
            <name>factory</name>
            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
            </parameter>

            <!-- Numero máximo de Conexiones activas. -->
            <parameter>
            <name>maxActive</name>
            <value>100</value>
            </parameter>

            <!-- Numero máximo de Conexiones latentes (idle). -->
            <parameter>
            <name>maxIdle</name>
            <value>30</value>
            </parameter>

            <!-- Tiempo máximo de espera para disponibilidad de una conexión 
                 en ms, (10000 ms = 10 segundos). -1 para indefinido.  -->
            <parameter>
            <name>maxWait</name>
            <value>10000</value>
            </parameter>

            <!-- Parámetros de usuario y contrase#241;a para conectarse a 
                    la Base de Datos  -->
            <parameter>
            <name>username</name>
            <value>web</value>
            </parameter>
            <parameter>
            <name>password</name>
            <value>osmosis</value>
            </parameter>

            <!-- Clase del driver JDBC -->
            <parameter>
            <name>driverClassName</name>
            <value>com.mysql.jdbc.Driver</value>
            </parameter>

            <!-- URL de Conexión para la Base de Datos 
                El argumento autoReconnect=true asegura que una conexión pueda ser 
                reestablecida por el driver una vez cerrada por el Driver.   -->
            <parameter>
            <name>url</name>
            <value>jdbc:mysql://localhost:3306/cursojsp?autoReconnect=true</value>
            </parameter>

            <!-- Parámetro utilizado para limpiar/eliminar cualquier conexión 
                 abandonada, como aquellas que no llaman el método close() -->
            <parameter>
            <name>removeAbandoned</name>
            <value>true</value>
            </parameter>

            <!-- Tiempo en segundos para que una conexión sea considerada  
                 abandonada  -->
            <parameter>
            <name>removeAbandonedTimeout</name>
            <value>60</value>
            </parameter>


         </ResourceParams>

       </Context>

La configuración anterior representa un "Pool" de conexiones hacia la Base de Datos MySQL realizado a través del "Pool" DBCP de Apache. Para que dicho "Pool" pueda ser establecido por Tomcat el "Servlet Engine" requiere acceso a las librerías de Apache DBCP y el Driver para MySQL.

Estas librerías que incluyen los archivos JAR commons-dbcp.jar, commons-pool.jar y mysql-<numero-de-versión>.jar deben ser colocados en $TOMCAT_HOME/common/lib/ , donde $TOMCAT_HOME es el directorio de instalación de Tomcat.

Descritos los detalles de JNDI, a continuación se describe el resto del bloque try/catch/finally.


      // BLOQUE try/catch/finally continuado 

     // Verificar si existe usario por Id
       
       String sql_busca = "select * from CURSOJSP_ENCUESTA where id = ?";

       PreparedStatement statement = conn.prepareStatement(sql_busca);
       statement.setString(1,id);
       
       ResultSet result = statement.executeQuery();
       boolean rs = result.next();
       if (rs) 
	   { 
	       // Si existe el usario colocar valores de la Base de Datos 
	       // en Variables
	       String nombre =  result.getString(2);
	       String apellido = result.getString(3);
	       int ciudadPrim = result.getInt(4);
	       int servicioPrim = result.getInt(5);
	       int areaPrim = result.getInt(6);
	       String email = result.getString(7);

	       // Los valores extraidos de la Base de Datos 
	       // son un integer primitivo. 
	       // Para que estos valores pueden ser colocados en la sesion
	       Integer ciudad = new Integer(ciudadPrim);
	       Integer servicio = new Integer(servicioPrim);
	       Integer area = new Integer(areaPrim);

	       // Llamar pagina para modificar datos
	       // Colocar los valores extraidos de la Base de Datos
	       // en el Objeto Session
	       
	       
	       HttpSession session = request.getSession();
	       session.setAttribute("nombre",nombre);
	       session.setAttribute("apellido",apellido);
	       session.setAttribute("ciudad",ciudad);
	       session.setAttribute("servicio",servicio);
	       session.setAttribute("area",area);
	       session.setAttribute("email",email);
	       session.setAttribute("id",id);


	       // Redireccionar directamente a JSP para modificar Datos
	       RequestDispatcher dispatch = getServletContext().getRequestDispatcher("/servidordatos/actualizarConf.jsp");
	       
	       dispatch.forward(request, response);
	   } else { 
	       
	       request.setAttribute("razonrechazo", "no existe el usario con el numero seleccionado");
	       
	       rechazarActualizar(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(" Ocurrió un error en la base de Datos mientras se intentaba actualizar datos", exc);
	
	request.setAttribute("razonrechazo", "ocurrió un error en la Base de Datos");
	
	rechazarActualizar(request,response);
	
    }  catch  (NamingException exc)  { 
	// Registrar posibles error en JNDI hacia registros ("Logs") 
	// Actualizar requisicion y llamar funcion de Rechazo 
	
	
	getServletContext().log(" Ocurrió un error al intentar accesar contexto JNDI", exc);
	
	request.setAttribute("razonrechazo", "ocurrió un error en la Base de Datos");
	
	rechazarActualizar(request,response);
	
    } finally {        	
       	// Cerrar Conexion
	try { 
	conn.close();	
	} catch (Exception exc) { 
	    getServletContext().log(" Ocurrió un error al intentar cerrar conexion hacia Base de Datos", exc);	    
	} 

    }  
    
 } // Termina Metodo Service 

  • Se define una secuencia de búqueda para verificar que el usuario (id) proporcionado 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.

  • A travé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 usuario (id), 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 usuario (id) en la Base de Datos, si dicho usuario (id) existe ocurre lo siguiente :

    • Se extraen los valores de la búsqueda y son colocados en sus respectivas variables.

    • Posteriormente se colocan estos mismos valores en la sesión del usuario; nótese que algunos de estos valores tuvieron que ser manipulados con anterioridad debido a que ciertos valores son del tipo integer primitivo y en el Objeto session estos deben ser colocados como Integer (Objeto).

      "Java Beans" en session

      El proceso de colocar las diversas variables dentro del objeto session individualmente puede ser un proceso muy tedioso, ante este tipo de diseños resulta ideal emplear "Java Beans", el uso de "Java Beans" en este tipo de situaciones será descrito posteriormente.

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

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

En caso de no existir el usuario (id) en la Base de Datos:

  • Se invoca el método rechazarActualizar con los Objetos request y response indicando el tipo de error que ocurrió (NOTA: El método rechazarActualizar se describe posteriormente).

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

  • Se define la sección catch del Bloque, la cual también invoca el método rechazarActualizar en caso de ocurrir un error imprevisto en la conexión o en la búsqueda JNDI.

  • Finalmente se define la sección finally que cierra la conexión hacia la Base de Datos.


    
    /** Redirecciona Errores a un Java Server Page **/
    
    public void rechazarActualizar(HttpServletRequest request, HttpServletResponse response) 
throws java.io.IOException, ServletException    {
	
	RequestDispatcher dispatch = getServletContext().getRequestDispatcher("/servidordatos/error.jsp");
	
	dispatch.forward(request, response);
	
    }
    

El método rechazarActualizar definido anteriormente es invocado en caso de ocurrir cualquier tipo de error en la Base de 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.

Terminos Legales de Contenido ©2000-2011 Osmosis Latina

Diseñado bajo estándares : XHTML   CSS  

webmaster@osmosislatina.com