AJAX usando JQuery y Struts

Hace ya un buen rato que no escribo nada por falta de tiempo y exceso de trabajo. Esta vez me toca escribir algo de programación para quienes requieran un ejemplo rápido de cómo comenzar a incluir AJAX en su aplicación.
Decidí usar Struts (1.x) en este ejemplo ya que muchas aplicaciones existentes usan este framework y es muy comun que en el mantenimiento de estas aplicaciones se desee agregar alguna funcionalidad que utilice AJAX. Por otro lado el uso de la biblioteca JQuery es una forma rápida y eficiente de escribir código Javascript, pues nos evitamos de complicaciones innecesarias excribiendo código javascript para tareas comunes, además de que es muy fácil de entender y aprender.

Dejo el ejemplo de AJAX en el siguiente archivo zip que es un proyecto Web para NetBeans 6.1, espero que les sea de utilidad.

Pueden descargar el archivo desde aquí: Ejemplo de Ajax
Este archivo está alojado con el servicio de http://www.sendspace.com

Brevemente explicaré aquí los archivos más importantes, comenzaremos con el archivo de configuración de struts:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">

<struts-config>
    <form-beans>
    
    </form-beans>
    
    <global-exceptions>
    
    </global-exceptions>

    <global-forwards>
        <forward name="welcome"  path="/Welcome.do"/>
    </global-forwards>

    <action-mappings>
        <action path="/Welcome" forward="/welcomeStruts.jsp"/>
        <action path="/saludoAjax" type="corp.neko.ajaxdemo.struts.SaludoAjax"/>
    </action-mappings>
    
    <controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>

    <message-resources parameter="corp/neko/ajaxdemo/struts/ApplicationResource"/>    
    
    <plug-in className="org.apache.struts.tiles.TilesPlugin" >
        <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />      
        <set-property property="moduleAware" value="true" />
    </plug-in>

    <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
        <set-property
            property="pathnames"
            value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
    </plug-in>
  
</struts-config>

– En la línea 21 definimos un redireccionamiento para la ruta /Welcome.do que va al archivo jsp que utilizaremos como ejemplo.
– En la línea 22 asociamos una acción para la ruta /SaludoAjax.do definida en la clase “corp.neko.ajaxdemo.struts.SaludoAjax”. Es destacable que no estamos definiendo ningún tipo de redireccionamiento, es decir, la acción se va a realizar sin ningún tipo de redirección una vez que esta se ha ejecutado.

Ahora analicemos la clase “corp.neko.ajaxdemo.struts.SaludoAjax” que realizará la acción:

package corp.neko.ajaxdemo.struts;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 *
 * @author abunai
 */
public class SaludoAjax extends Action{
    
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){
        
        response.setContentType("text/xml");
        response.setHeader("Cache-Control", "no-cache");        
        String nombre = request.getParameter("nombre");
        try {
            PrintWriter writer = response.getWriter();
            writer.print("<xml><respuesta><!&#91;CDATA&#91;¡Hola "+nombre+"! Este es un ejemplo de AJAX&#93;&#93;></respuesta></xml>");
            writer.flush();
            writer.close();
        } catch (IOException ex) {
            Logger.getLogger(SaludoAjax.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return null;
    }

}

La idea de esta clase es generar una respuesta de tipo xml recibiendo algunos parámetros vía “Request”.
– En la línea 23 y 24 tomamos el objeto de tipo HttpServletResponse que es pasado como parámetro al método execute y lo preparamos para dar una salida de tipo xml. Es muy importante prevenir que los exploradores guarden en caché el recurso, pues nuestro xml cambiará de acuerdo a los parámetros que se envíen en la petición.
– En las líneas 27-30 generamos la salida xml, hay que destacar que en la respuesta estamos poniendo un CDATA, esto para evitar cualquier problema de interepretación de caracteres reservados y especiales que pudiese contener nuestra respuesta.

Finalmente analizaremos nuestra página de prueba welcomeStruts.jsp:

<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %>

<html:html locale="true">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title><bean:message key="welcome.title"/></title>
        <script type="text/javascript" src="js/jquery-1.2.6.js"></script>
        <script type="text/javascript">
            $(function(){
                $("#usuario").blur(validaUsuario);
            });
            
            function validaUsuario(){
                var name = $("#usuario").val();                
                $.get("/AjaxExample/saludoAjax.do", { nombre: name }, 
                    preparaRespuesta
                );
            }
            
            function preparaRespuesta(data){
                        var respuesta = $(data).find("respuesta").text();
                        $("#respuesta").hide();
                        $("#respuesta").empty();
                        $("#respuesta").append(respuesta);
                        $("#respuesta").show("slow");
                    }
        </script>
        <html:base/>
    </head>
    <body style="background-color: white">
        
        <logic:notPresent name="org.apache.struts.action.MESSAGE" scope="application">
            <div  style="color: red">
                ERROR:  Application resources not loaded -- check servlet container
                logs for error messages.
            </div>
        </logic:notPresent>
        
        <h3><bean:message key="welcome.heading"/></h3>
        <p><bean:message key="welcome.message"/></p>
        <input name="usuario" id="usuario" type="text">
        
        <div id="respuesta"></div>
        
    </body>
</html:html>

– En las líneas 14-16 declaramos una función anónima cuyo contenido se ejecutará antes de cargar la página, es decir este es el lugar indicado para escribir toda la funcionalidad requerida por el documento antes de comenzar a interactuar con él.
– En la línea 15 destacan dos cosas, la primera es la forma de hacer referencia a un componente de la página utilizando el id: “#componenteX”, que en este caso hace referencia al componente de entrada de texto con id “usuario”. La segunda es que se aplica una función al elemento de acuerdo al evento que se especifique, en este caso “blur”.
– En las líneas 18-23 se define la función que se ejecutará en el evento “blur”, en la línea 19 se recupera el valor que contenga el elemento “usuario”. Las líneas 20-22 son la llamada Ajax a /saludoAjax.do, se especifica que la llamada va a contener un parámetro de nombre “nombre” y cuyo valor es el de la variable “name”. Finalmente se especifica un tercer parámetro, el cual es la función que se ejecutará una vez recibida la respuesta de la llamada Ajax.
– En las líneas 25-31 definimos la función que se ejecutará con el resultado de la llamada a /SaludoAjax.do la cual recibe como parámetro una variable “data” que es el xml que generamos en el método action. En la línea 26 obtenemos el valor de “respuesta” utilizando el método “find” de JQuery. En las líneas 27-31 se manipula el elemento div con id “respuesta” para insertar y mostrar el contenido obtenido en 26.

Anuncios
Acerca de

Estudiante de la Facultad de Ciencias UNAM, desde hace unos años. Soñador y loco, enamorado...

Publicado en Programación
19 comments on “AJAX usando JQuery y Struts
  1. aNGeLuS dice:

    Me parece interesante, incluso me causa k investigue un poco más al respecto, solo me quede con una duda que creo es importante: ¿Y el archivo zip que mencionas? ¿Como o de donde lo descargo?

  2. Andres dice:

    Muchas Gracias por compartir tus conocimientos. Estaba buscando hace semanas algo similar para
    trabajar con ajax y struts para mi proyecto de título.

  3. flavin dice:

    Podrias poner un breve ejemplo acá y no solo para descargar 😦

  4. Diego dice:

    Buenas antes que nada gracias por esto!, estoy trabajando con struts, y me pidieron que mejore las vistas!!!; por lo que empece a pensar en jquery ya que tiene muchas cosas interesantes!!!, asi que tu ayuda me viene de pelos!!! gracias!!.

  5. abunaineko dice:

    Además de Jquery podrías considerar usar Dojo, que está un poco mas completo en cuanto a cuestiones visuales, voy a tratar de ponder un ejemplo similar a este pero usando Dojo.

  6. Luz dice:

    Mira el archivo que subiste esta dañado por favor si podrias enviarmelo a mi correo o verificar y montarlo de nuevo, te lo agradeceria muchisimo.

    Saludos

  7. abunaineko dice:

    Hola Luz!
    Verifiqué el link hace unos instantes y el archivo no tiene ningún problema. Verifica la descarga por favor!
    Saludos

  8. Lolo dice:

    Alguien ha probado el código con I Explorer 6? No funciona si se obtienen varias en el Action; (puede que se deba al parseo del xml).

  9. Lolo dice:

    Quiero decir que si obtengo varias respuestas en el action (resultado de una consulta con base de datos) no funciona en I Explorer, y en Firefox si. ¿Alguna sugerencia?

  10. abunaineko dice:

    Pues he verificado que el código es usable en los exploradores que mencionas e incluso en safari. la idea de las bibliotecas de javascript como JQuery es la compatibilidad entre exploradores.
    Mencionas algo de bases de datos, no se si puedas ser mas concreto, de cualquier modo verifica la codificación de caracteres de tu BD y revisa que pases los resultados como CDATA.

  11. Lolo dice:

    Utilizo este mismo ejercicio para hacer un combo anidado, en base de datos tengo una tabla con todas provincias de españa y otra con todas las poblaciones y sus respectivos códigos. A el action le paso el id de provincia tras seleccionarlo en el select, tras lo cual realizo una consulta a base de datos y obtengo las poblaciones pertinentes que almaceno en una lista, que luego recorro:
    //obtengo todas las poblaciones en funcion de la provincia
    PoblacionBO poblacionBO=new PoblacionBO();
    poblaciones=new LinkedList(poblacionBO.findbyProvincia(Integer.parseInt(id)));
    Iterator iterator=poblaciones.iterator();
    writer.print(“”);
    while(iterator.hasNext()){
    Poblacion poblacion=(Poblacion)iterator.next();
    writer.print(“”+poblacion.getIdPoblacion()+””);
    }
    writer.print(“”);
    log.debug(writer);
    writer.flush();
    writer.close();
    En firefox funciona sin ningun problema, el 2º combo cambia bien pero en explorer parece como si ni siquiera entrara en la funcion del jsp tras pasar por el action.
    Funcion del jsp que se encarga del recuperar los datos y crea el combo de las poblaciones:
    function carga1(data){
    $(“#poblaciones”).empty();
    var texto=$(data).find(“poblacion”);
    //recorre los elementos del array
    jQuery.each(texto,function(i){
    $(“#poblaciones”).append(“”+texto[i].childNodes[1].firstChild.nodeValue+”–“+texto[i].firstChild.nodeValue+”</option”);
    });
    Un saludo

  12. Lolo dice:

    Disculpar, vuelvo a escribir el codigo obviando la apertura y cierre de etiquetas por – para que no se omitan.
    writer.print(“-xml-“);
    while(iterator.hasNext()){
    Poblacion poblacion=(Poblacion)iterator.next();
    writer.print(“-poblacion–![CDATA[“+poblacion.getNombrePoblacion()+”]]–id-“+poblacion.getIdPoblacion()+”-/id–/poblacion-“);
    }
    writer.print(“-/xml-“);
    log.debug(writer);
    writer.flush();
    writer.close();
    funcion del jsp:
    function carga1(data){
    $(“#poblaciones”).empty();
    var texto=$(data).find(“poblacion”);
    //recorre los elementos del array
    jQuery.each(texto,function(i){
    $(“#poblaciones”).append(“-option value=\””+texto[i].childNodes[1].firstChild.nodeValue+”\”-“+texto[i].childNodes[1].firstChild.nodeValue+”–“+texto[i].firstChild.nodeValue+”-/option-“);
    });
    }
    Gracias

  13. Hector Garcia dice:

    Ayuda….
    Porque no me funciona en Internet Explorer 7??

    no entra a la funcion preparaRespuesta ………..

  14. Vladimir Perez dice:

    tengo el mismo problema con iExplorer, es decir, no se muestra la informacion de #respuesta. En cambio en Firefox si se muestra el dato. Alguien nos puede ayudar o guiar para corregir esta situación?

  15. Hola amigo, perdona la molestia pero podrias resubir el archivo, ya no esta en linea, espero tu respuesta gracias.

  16. Alvaro Leon dice:

    a los que no les funciono con IE (cual sea la version) MS tiene un controlador exclusivo para ajax, me gustaria enviarles un ejemplo de este, sin embargo, tuve un accidente como mi equipo…., pero la idea es detectar cual es el cliente (browser) y a partir de ello llamar al controlador de ajax que corresponda

  17. Eleazar dice:

    Gracias!. Esto me ayudó bastante

  18. Patricia dice:

    Puzzle books, including word finds and crossword puzzles, go a long way at
    passing time quickly. In a garage wedding shower, the
    groom is assigned anything and everything he may need for
    his garage and also to keep up with outside chores and home maintenance.
    There are times when all you need is to provide your man something fancy and you turn out being annoyed because that “something” seems being so away from reach.

  19. julian dice:

    el archivo no esta disponible 😦

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

Categorías
A %d blogueros les gusta esto: