Como criar meu proprio Bean Faces EL Resolver?

6 respostas
lindberg713

Criei um mecanismo de injeção de dependencia para fazer uns testes aqui e queria integra-lo ao jsf de modo que funcione parecido como o SpringBeanFacesELResolver onde eu não precise declarar meus ManagedBeans no faces-config de modo que eu chame um managedBean na minha pagina pelo ID do bean. Como por exmeplo : #{meuMB.incluir} onde meuMB é o ID meu bean no meu container de injeção de dependencias. Resumindo quero dizer ao jsf como quero que ele encontre o managedBean.

Alguem pode me ajudar?

Obrigado

6 Respostas

lindberg713

Já resolvi. Tava faltando chamar elContext.setPropertyResolved(true); na implementação do meu ElResolver.

elugo

Poderia postar o código?
estou precisando fazer exatamente isso!
vlw

lindberg713

Cara meu ElResolver ta funcionando blz no componente que desenvolvi. Nao sei se vai dá pra vc entender mas abaixo vai o fonte, qualquer dúvida me reporta ai.

package org.lindbergframework.integration.web.jsf.el;

import javax.el.BeanELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.lindbergframework.beans.di.context.BeanFactory;
import org.lindbergframework.beans.di.context.UserBeanContext;

/**
 * 
 * Lindberg {@link ELResolver} implementation to integrate JSF layer with
 * lindberg IOC context beans.
 * 
 * @author Victor Lindberg
 *
 */
public class LindbergBeanJsfResolver extends BeanELResolver {
    
    /**
     * Bean factory implementation.
     */
    private BeanFactory beanFactory;
    
    /**
     * Bean repository.
     */
    private BeanRepositoryByResponse repository;
    
    public LindbergBeanJsfResolver(){
        beanFactory = getBeanFactory();
        repository = new BeanRepositoryByResponse(beanFactory);
    }

    /**
     * Get bean instances of lindberg IOC context if the property corresponds to
     * a bean id.
     * 
     * @return bean instance or null if bean for id specified not found.
     */
    @Override
    public Object getValue(ELContext elContext, Object base, Object property) {
        if (base == null && property != null){
           ResponseBeans responseBeans = getResponseBeans();
           String idBean = property.toString(); 
           if (responseBeans.containsBean(idBean)){
              Object bean = responseBeans.getBean(idBean);
              elContext.setPropertyResolved(true);
              return bean;
           }
        }
        
        return null;
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public Class getType(ELContext context, Object base, Object property) {
        if (base == null && property != null)
           return beanFactory.getType(property.toString());
        
        return null;
    }
    
    public BeanFactory getBeanFactory(){
        return UserBeanContext.getInstance().getFactory();
    }
    
    /**
     * Get the {@link ResponseBeans} instance for this session and response.
     * 
     * @return {@link ResponseBeans} instance for this session and response.
     */
    public ResponseBeans getResponseBeans(){
        HttpServletResponse resp = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
        
        ResponseBeans responseBeans = repository.getResponseBeans(session);
        if (responseBeans != null){
           if (! responseBeans.getResponse().equals(resp)){
               responseBeans = repository.registerResponse(session, resp);
           }
           
           return responseBeans;
        }   
            
        return repository.registerResponse(session, resp);
        
    }
    
    
}
AdemirPinto

Fala pessoal,

alguem poderia me responder o que é ELResolver? Estou começando no JSF, o que está acontecendo é que quando preciso dos dados de MB retorna NULL se eu uso assim:

return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(nomeObjeto);

Mas funciona se eu usar assim:

FacesContext context = FacesContext.getCurrentInstance();
ELResolver resolver = context.getApplication().getELResolver();
return resolver.getValue(context.getELContext(), null, valorObjeto);

Alguem sabe pq o segundo código funciona e me retorna o MB nao nulo?

Grato
Ademir

lindberg713

Cara um ELResolver é um resolvedor de valores dentro de um contexto a partir de uma Expressão, ao qual chamamos de Expression Language (EL). Entao digamos que temos a expressão #{clientesMB.cliente.nome} então o ELResolver do JSF é responsável por interpretar essa expressão e devolver o valor da propriedade ‘nome’, dentro do objeto ‘cliente’, que é uma propriedade que está dento do ManagedBean clientesMB. Esse clientesMB, neste caso, é um bean do contexto do JSF, então o ELResolver vai baseado na exprssao encontrar a instancia adequada e obter o valor solicitado na expressão.

Respondendo sua outra pergunta, o seu primeiro trecho de código não funciona por que o método getSessionMap() retorna um Map imutável com os atributos adicionados a sessão do usuário, apenas isso e esse map não terá os ManagedBeans do JSF que vc criou pois estes estão dentro do contexto do JSF e não como atributos da sessão do usuário.
Então quando vc faz:

getSessionMap().get(nomeObjeto);

O map retornado nao tem o bean que vc procura pois este esta dentro do contexto jsf e nao na sessão do usuário explicitamente.
Ressalto que esses beans poderão sim estar como atributos na sessão do usuário, mas apenas se vc definir no seu faces-config eles como sendo de escopo de session ou se vc simplesmente em algum momento adicionar algum destes a sessão do usuário explicitamente.

O seu segundo trecho funciona pq vc obtem o ELResolver do contexto do JSF, agora sim, a partir desse resolver vc pode obter qualquer valor de qualquer ManagedBean do JSF.

Quando vc faz

FacesContext context = FacesContext.getCurrentInstance(); ELResolver resolver = context.getApplication().getELResolver(); return resolver.getValue(context.getELContext(), null, valorObjeto);

Observe que vc obtem o ELResolver do contexto do JSF, o FacesContext. Por isso funciona.

Espero ter ajudado.

AdemirPinto

lindberg713:
Cara um ELResolver é um resolvedor de valores dentro de um contexto a partir de uma Expressão, ao qual chamamos de Expression Language (EL). Entao digamos que temos a expressão #{clientesMB.cliente.nome} então o ELResolver do JSF é responsável por interpretar essa expressão e devolver o valor da propriedade ‘nome’, dentro do objeto ‘cliente’, que é uma propriedade que está dento do ManagedBean clientesMB. Esse clientesMB, neste caso, é um bean do contexto do JSF, então o ELResolver vai baseado na exprssao encontrar a instancia adequada e obter o valor solicitado na expressão.

Respondendo sua outra pergunta, o seu primeiro trecho de código não funciona por que o método getSessionMap() retorna um Map imutável com os atributos adicionados a sessão do usuário, apenas isso e esse map não terá os ManagedBeans do JSF que vc criou pois estes estão dentro do contexto do JSF e não como atributos da sessão do usuário.
Então quando vc faz:

getSessionMap().get(nomeObjeto);

O map retornado nao tem o bean que vc procura pois este esta dentro do contexto jsf e nao na sessão do usuário explicitamente.
Ressalto que esses beans poderão sim estar como atributos na sessão do usuário, mas apenas se vc definir no seu faces-config eles como sendo de escopo de session ou se vc simplesmente em algum momento adicionar algum destes a sessão do usuário explicitamente.

O seu segundo trecho funciona pq vc obtem o ELResolver do contexto do JSF, agora sim, a partir desse resolver vc pode obter qualquer valor de qualquer ManagedBean do JSF.

Quando vc faz

FacesContext context = FacesContext.getCurrentInstance(); ELResolver resolver = context.getApplication().getELResolver(); return resolver.getValue(context.getELContext(), null, valorObjeto);

Observe que vc obtem o ELResolver do contexto do JSF, o FacesContext. Por isso funciona.

Espero ter ajudado.

Valeu lindberg713,

Tendi o que vc disse…muito bem explicado.

Interessante que para setar o MB eu nao preciso do ELResolver, eu uso conforme abaixo:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(nomeObjeto, tipoObjeto);

Abraços e muito obrigado.
Ademir

Criado 28 de setembro de 2010
Ultima resposta 13 de jul. de 2011
Respostas 6
Participantes 3