Consultar base de datos cada X segundos – java ajax jsf

Pregunta:


Lo que necesito hacer es lo siguiente, no sé porque pero si se actualiza un dato en base de datos no me lo pinta de una vez en mi vista, debo volver a correr mi proyecto para ver la actualización del dato. Me gustaría hacer un método que cada 5 segundos consulte la base de datos y me actualice el dato que quiero.

Me han dicho que puedo hacerlo con f:ajax pero no lo sé utilizar, si me pudieran dar un ejemplo para guiarme lo agradecería mucho.

La base de datos es MySQL, utilizo JavaServerFaces y la conexión la realizo por medio de JPA.

Preguntado por: Lina Cortés

Comunidad

La estrategia explicada en la respuesta de @PabloPéres-Aradros es una solución conocida como polling. Esto eso, el cliente consulta cada cierto tiempo al servidor. Debes utilizar setInterval para que un método se ejecute en un intervalo de tiempo. Sucede que JSF, por defecto, coloca ciertos parámetros en el cliente para asegurarse del estado de la vista y así evitar los ataques CSRF, de manera que utilizar el método que explica Pablo no resulta “tan sencillo” al utilizar JSF al hacerlo todo manualmente. De todas formas, JSF sí soporta realizar poll.

Si utilizas JSF puro, lo mejor sería delegar la acción a un componente con <f:ajax>:

<h:form id="idForm">
    <!-- ... contenido ... -->
    <!-- Nota: el componente DEBE ser visible, sino no se ejecutará. -->
    <h:commandButton id="idBoton" action="#{bean.metodoParaRefrescar}">
        <f:ajax render="idComponenteARefrescar" />
    </h:commandButton>
    <!-- ... contenido ... -->
</h:form>

Y crear una función JavaScript:

setInterval(function() {
        document.getElementById("idForm:idBoton").click()
    }, 3000); //cada 3 segundos, adáptalo a tus necesidades

Si utilizas una librería como PrimeFaces, considera que ya provee un componente propio para hacer poll (código adaptado de la página de ejemplos de PrimeFaces).

<h:form id="idForm">
    <h:outputText id="txtContador" value="#{bean.numero}" />
    <!--
        Cada 3 segundos ejecutar una petición y ejecutar
        de lado del servidor el método declarado en listener
    -->
    <p:poll interval="3" listener="#{bean.incrementar}"
        update="txtContador" />
</h:form>

Considera esto como un ejemplo simple. Tu método de lado del servidor puede ejecutar las llamadas a base de datos necesarias. Asimisimo, deberías medir el tiempo de respuesta del servidor y de actualización de la página para colocar el valor de tu intervalo.

Existe otra estrategia que se llama push, que consiste en que el servidor ejecuta las operaciones en intervalos de tiempo y notifica al cliente que debe actualizarse. BalusC (gurú en Java y JSF) explica cómo utilizar push en JSF en esta respuesta, traducido parcialmente:

Hasta el nuevo de JSF 2.3 <f:websocket> (issue 1396), la librería estándar de JSF no ofrece facilidades para esto. Necesidas acudir a librerías de terceros por ahora:

El nuevo componente de JSF 2.3 <f:websocket> está ampliamente basado en <o:socket>.

Para la descripción de tu problema, en mi opinión, usaría polling. De todas formas, corresponde a ti evaluar las alternativas y elegir la más conveniente a utilizar.

te hago un ejemplo de como sería el código ajax:

function ajax() {          

        var oReq = new XMLHttpRequest();
        oReq.open("POST", "tufuncionphp.php", true);

        oReq.onload = function (oEvent) {
            if (oReq.status == 200) {
                document.getElementById("divobjetivo").innerHTML = oReq.responseText;
            }
        };
        oReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        oReq.send(datos);
}

Te explico, para que funcione ajax, siempre hay que crear un objeto tipo XMLHttpRequest.

Lo indispensable es que en el objeto.open, introduzcas si es tipo POST o GET y la URL de tu PHP.

La función de objeto.onload se ejecuta cuando el código de PHP se ha ejecutado. El método .responseText, recoge el texto de respuesta de PHP, y luego ya lo insertas donde quieras, en mi ejemplo lo dejo preparado para que lo metas en un campo especificado por una id. En el document.getElementById(“divobjetivo”), cambia el divobjetivo por la id de tu elemento donde quieras recargar la informacion.

Por último, es en objeto.send(), se pasan los campos que quieres enviar para simular el envío de un formulario a el PHP, en formato “dato1=datos&dato2=datos2”.

Si quieres que esto se ejecute cada 5 segundos, introduces el código en un setInterval, tal que así.

function ajax() {          
setInterval(function(){
        var oReq = new XMLHttpRequest();
        oReq.open("POST", "tufuncionphp.php", true);

        oReq.onload = function (oEvent) {
            if (oReq.status == 200) {
                document.getElementById("divobjetivo").innerHTML = oReq.responseText;
            }
        };
        oReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        oReq.send(datos);

},5000);
}

Espero haberme explicado bien. Un saludo.

Para eso se tiene dos opciones una es que justo un momento antes de que tu consulta te regrese el resultado del comando se ejecute un comando select donde se llame nuevamente todo lo que tenga esa tabla.
La otra es la misma forma pero usando lo que con temporizadores para que cada cierto tiempo la sentencia se vuelva a ejecutar nuevamente.

Fuente

Tags:, ,

Add a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *