Mentawai Web Framework

VOFilter e OVFilter

O objetivo do filtro org.mentawai.filter.VOFilter (Value-Object Filter) é popular um objeto com os valores presentes no input da action. Isso pode ser útil na hora de manipular os dados de um formulário já que ao invés de fornecer para sua action um monte de parâmetros soltos, você pode entregar um objeto populado com os dados. Esse objeto não precisa estender nenhuma classe do Mentawai em específico e é apenas um objeto como outro qualquer (POJO).

O funcionamento do VOFilter se resume em tentar injetar todos os parâmetros do input da action num objeto recém-criado via reflection. Ele também é capaz de injetar um valor diretamente num campo público ou privado. A regra é: primeiro tente através de um setter (setUsername, setFirstName, etc.). Se não funcionar tente injetar diretamente no campo (username, firstName, etc.) mesmo que esse campo seja privado.

Coisas que você deve notar sobre o VOFilter:

  • Talvez você tenha que converter alguns valores (consulte Conversão) antes que o seu VOFilter possa injetar com sucesso esses valores dentro do seu objeto. Entretanto, para conversões simples de String para inteiros, double, boolean e short dates, essa conversão será tentada automaticamente pelo filtro, que olhará para o tipo do campo através de reflection, ou seja, não é preciso usar um conversor.

  • O VOFilter não joga nenhuma exception. Ele tenta da melhor maneira possível injetar os valores do input no objeto em questão, mas se ele não conseguir encontrar um método setter ou um campo apropriado, ele irá ignorar aquele valor e passar para o próximo. Lembre-se que outros valores, não relacionados ao seu objeto podem estar no input durante esse processo e o VOFilter não tem como saber quais deles pertencem ao seu objeto. Mas isso não é problema, pois como falamos aqui, os valores que não puderem ser injetados são ignorados.

  • Depois que o objeto é populado, o VOFilter vai colocá-lo no input da action utilizando a chave passada (Ex: "myObject") ou o nome da classe do objeto (Ex: "org.myproject.User") caso nenhuma chave tenha sido passada.

  • O VOFilter não retira nenhum parâmetro do input da action. Os valores que são injetados no objeto permanecem no input da action.

  • Se você estiver populando vários objetos ao mesmo tempo na mesma requisição e algum deles tiverem propriedades em comum (Ex: client.nome, empresa.nome) como o VOFilter vai poder diferenciá-los ? A resposta está em utilizar um prefixo junto com o VOFilter. Dessa maneira o seu VOFilter só vai pegar os parâmetros que possuem o prefixo e ignorar todos os outros. Na hora de injetar no objeto ele removerá o prefixo para obter o nome correto da propriedade. Dessa maneira nada impede de você popular dois objetos diferentes usando dois VOFilters na mesma requisição. Para setar o prefixo tudo que vc tem que fazer é passá-lo no construtor do VOFilter.

  • Se por algum motivo você desejar, você pode também desabilitar a conversão automática e/ou a injeção direta em campos utilizando a versão apropriada do construtor do VOFilter. Para mais detalhes consulte a documentação da API.

import org.mentawai.core.*;
import org.mentawai.filter.*;

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
	
    public void loadActions() {
		
        ActionConfig ac = new ActionConfig("/Hello", HelloVOFilter.class);
        ac.addConsequence(SUCCESS, fwd("/show.jsp"));
        ac.addConsequence(ERROR, fwd("/user.jsp"));
        addActionConfig(ac);
        
        ac.addFilter(new VOFilter(User.class)); // populate a User object and place it in the action input with "org.myprof.User" key
        
        // or
        
        ac.addFilter(new VOFilter(User.class, "user")); // populate a User object and place it in the action input with "user" key
        
        // or
        
        ac.addFilter(new VOFilter(User.class, "user", true)); // populate a User object and place it in the action input with "user" key
                                                              // also try to inject directly into the fields, public or private
    }
}

					


OVFilter

O org.mentawai.filter.OVFilter (Object-Value filter) faz exatemento o oposto do VOFilter. Ele procura por um objeto no output da action e tenta extrair todas as suas propriedades e colocá-las no output da action. Esse procedimento é bastante útil quando você precisa exibir todas as propriedades de um objeto dentro de um formulário html, por exemplo. Consulte a seção Tags de HTML para entender como o Mentawai pode exibir os valores do output da action automaticamente dentro do seu formulário web, sem que você precisa escrever uma linha de código para tal.

Coisas que você deve notar sobre o OVFilter:

  • Ao contrário do VOFilter, ele não vai acessar campos privados do seu objeto. O seu objeto deve oferecer getters (getUsername(), getFirstName(), etc.) para que o OVFilter possa ser capaz de extrair suas propriedades.

  • O OVFilter chama também os métodos getters das classes acima (superclasses), em outras palavras, realmente todas as propriedades do seu objeto serão extraídas e colocadas no output da action.

  • Você deve passar para o construtor do OVFilter a chave com a qual ele vai procurar o objeto no output da action.

import org.mentawai.core.*;
import org.mentawai.filter.*;

public class ApplicationManager extends org.mentawai.core.ApplicationManager {
	
    public void loadActions() {
		
        ActionConfig ac = new ActionConfig("/Hello", HelloOVFilter.class);
        ac.addConsequence(SUCCESS, fwd("/show.jsp"));
        ac.addConsequence(ERROR, fwd("/user.jsp"));
        addActionConfig(ac);
        
        ac.addFilter(new OVFilter("user")); // look for an object with the "user" key in the action output and extract its properties
                                            // placing them in the action output.
    }
}				


InjectionFilter e OutputFilter

Da mesma maneira que nós temos o VOFilter e OVFilter, o Mentawai também oferece o InjectionFilter e OutputFilter. Eles se comportam da mesma maneira exceto que o InjectionFilter tenta injetar os valores do input da action diretamente na action e não num objeto qualquer. O OutputFilter por sua vez tentará pegar todas as propriedades da action e colocá-las no output da action.

Você pode utilizar o InjectionFilter e o OutputFilter para não ter que utilizar o input e o output dentro das suas actions.

Note que o Injection/Output Filter possuem um papel fundamental quando temos um design model-driven para nossas actions. Em outras palavras, o InjectionFilter irá detectar que a action implementa a interface ModelDriven e vai injetar os valores do input não diretamente na action mais no modelo retornado pelo método getModel(). Mesma coisa acontecerá com o OutputFilter que pegará as propriedades diretamente do modelo e não da action.