Mentawai Web Framework

Integração com Ajax

Ajax (Asynchronous Javascript and XML) leva as suas aplicações a um nível de interação muito elevado. Se você usa GMail, por exemplo, você verá que o nível de interação deste webmail o torna muito poderoso. Você não precisa ficar recarregando a página para ver se novos e-mails chegaram. De modo assíncrono (ou seja, sem precisar recarregar), o webmail envia uma requisição para o servidor do GMail pedindo os novos e-mails. E isto é só um exemplo.
Por ser uma tecnologia tão poderosa, o Mentawai não podia simplesmente ignorar o Ajax.

O Mentawai possui vários helpers para se trabalhar com Ajax, uma API do lado do servidor para gerar uma resposta em forma de String para uma requisição Ajax baseada na output da action.
O Mentawai tem duas classes principais para a integração com Ajax: AjaxConsequence e AjaxRenderer. A partir da versão 1.11 o Mentawai também conta com uma poderosa e facilitadora biblioteca JavaScript no client-side, chamada [url="http://forum.mentaframework.org/posts/list/1418.page"]MentaAjax[/url], desenvolvida por Robert Willian.

O AjaxRenderer pega a output da action e a transforma em uma String que será usada como saída da requisição Ajax. Por exemplo, o Mentawai vem um um AjaxRenderer que pega uma coleção de beans da output da action e cria uma estrutura XML com os dados dos beans. Outro exemplo, o Mentawai tem um AjaxRenderer que pega um Map da output da action e cria uma estrutura XML baseada nos dados do Map. (Obs.: Usa-se estrutura XML nesses AjaxRenderers porque normalmente as respostas ás requisições Ajax são estruturas XML, parseadas por um parseador DOM embutido no JavaScript do navegador)
A String gerada pelo AjaxRenderer será usada pelo AjaxConsequence como a saída da requisição Ajax.
A sequência do tratamento de requisições Ajax no Mentawai é:

1 - O navegador faz uma requisição Ajax para uma aplicação web, em uma url mapeada por uma action do Mentawai.
2 - O Servlet Controller trata a requisição Ajax como uma requisição HTTP normal e passa ela para a action, como sempre.
3 - A action processa a requisição Ajax como se fosse uma requisição HTTP normal, gerando uma Output, como sempre.
4 - O AjaxRenderer pega um valor pré-definido do output da action (AjaxConsequence.KEY) e gera um XML, JSON, String, etc. para a resposta do AJAX. O conteúdo da String gerada depende da implementação do AjaxRenderer.
5 - A AjaxConsequence pega a String gerada pelo AjaxRenderer e usa ela como a saída da requisição Ajax.

Na verdade, tudo que você precisa fazer em usa aplicação Java é configurar a consequência da sua ActionConfig para usar o AjaxConsequence e usar uma das implementações da interface AjaxRenderer. Daí, na sua camada de visão, você vai precisar usar JavaScript para criar a requisição Ajax (XMLHttpRequest), acessando uma uma URL mapeada pela sua que tem uma AjaxConsequence configurada como consequência e usar JavaScript para processar a saída impressa pelo AjaxConsequence.

O Mentawai vem com algums AjaxRenderers, e, se você precisar de algo que não é coberto por essas classes, você pode facilmente desenvolver o seu AjaxRenderer (ou requisitar que alguém da equipe faça no fórum). O Mentawai não vem com uma API client-side para Ajax (quem sabe nas próximas versões), então você pode usar suas bibliotecas client-side de Ajax preferidas.

Abaixo, há um exemplo de como usar Mentawai+Ajax para preencher de modo assíncrono um <select>:

O ApplicationManager:

import org.mentawai.ajax.AjaxConsequence;
import org.mentawai.ajax.renders.MapAjaxRender;
import org.mentawai.core.ActionConfig;

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
    public void loadActions() {
        ActionConfig actionConfig = new ActionConfig("/getNames",SomeAction.class);
        actionConfig.addConsequence(SomeAction.SUCCESS, new AjaxConsequence(new MapAjaxRender()));
        addActionConfig(actionConfig); 
    }
}
                

O exemplo de uma Action:

import java.util.HashMap;
import java.util.Map;

import org.mentawai.ajax.renders.MapAjaxRender;
import org.mentawai.core.BaseAction;

public class SomeAction extends BaseAction {

	public String execute() throws Exception {
        Map map = new HashMap();
        map.put("1","Rubem Azenha");
        map.put("2","Sérgio Oliveira");
        map.put("3","Fernando Boaglio");
        map.put("4","Davi Luan Carneiro");
        output.setValue(AjaxConsequence.KEY, map);
        return SUCCESS;
        
	}

}
                

E a página:

<html>
<head>
<title>Mentawai + AJAX - Asyncronous JavaScript and XML</title>
</head>
<body>
<script>
var req;
var comp;

function createAjaxRequest() {
    var ajaxReq;
    if (window.XMLHttpRequest) { // Non-IE browsers
       ajaxReq = new XMLHttpRequest();
   }
    else if (window.ActiveXObject) { // IE
            ajaxReq = new ActiveXObject("Microsoft.XMLHTTP");
        }
    return ajaxReq;
}

function getValues() {
   var url = "getNames.mtw";
   comp = document.getElementById("list");
   req = createAjaxRequest();
   if (window.XMLHttpRequest) { // Non-IE browsers
     req.onreadystatechange = processStateChange;
    try {
        
           req.open("GET", url, true);
       } catch (e) { 
           alert(e);
       }
       req.send(null);
    } 
    else if (window.ActiveXObject) { // IE
       if (req) {
           req.onreadystatechange = processStateChange;
            req.open("GET", url, true);
            req.send();
        }
    }  
    
}
    
function processStateChange() {
    if (req.readyState == 4) {
        if (req.status == 200) { // OK response
            var xml = req.responseXML;
            var entries = xml.getElementsByTagName("entry");
            for (var i = 0; i < entries.length; i++) {
                var entry = entries[i];
                 comp.options[comp.length] = new Option(entry.firstChild.nodeValue,entry.getAttribute("key"));
            } 
        }
        else {
           alert("Problem: " + req.statusText);
       } 
    }
}
</script>
<br>
Click here to asynchronously put some values on the select bellow: <input type="button" value="OK" onClick="getValues();" />
<br>
<select id="list">
</select>
</body>
</html>