Mudança de contexto JSF

15 respostas
A

Pessoal, estou com um grande problema aqui.

Criei algumas aplicações em JSF, mas quando tento mudar o contexto, passando de uma aplicação para outra, eu perco todos os parametros.

Nesse caso específico, eu tento passar da tela de login (um sistema) para outro sistema qualquer (levando o usuário e senha).

Se alguem puder ajudar agradeço!

15 Respostas

G

No seu Faces Config como está seu Managed Bean Scope do Managed Bean que quer passar para outra aplicação?

Se não está SESSION, coloque:

<managed-bean-scope>session</managed-bean-scope>
A

Já testei tanto ‘session’, quanto ‘application’.
Sempre perde os valores, quando muda de contexto!

Teoricamente deveria usar o bean de ‘application’.

edit:
Para mudar o contexto estou fazendo assim: facesContext.getCurrentInstance().getExternalContext().redirect(“sistema”);
Existe outra forma melhor para fazer isso?

P

Olá! Estou com a mesma dúvida!!
Estou fazendo um portal utilizando jsf, e ainda não achei uma solução realmente interessante para isso.
Porém, eu consegui acessar outros contextos redirecionando o link através de href. Tais links recuperavam o conteúdo de outro contexto perfeitamente, mas dae esbarrei em outro problema: toda lógica de fluxo de páginas do jsf é perdido, sendo que os “creates” para cada bean não mais estão sendo acessados, retornando null para as propriedades.

Alguém tem mais alguma idéia ?

C

Ao meu ver, se está em contexto diferente são aplicações diferentes.

O Application para todos os usuários que acessam dentro de um mesmo contexto. Logo, vc não deveria usar o Application para guardar um login, a não ser que seja um mesmo login para todos usuários, o que é inaplicável.

Ou vc joga a duas aplicações num mesmo contexto, e cria uma pasta para cada aplicação:

ex: http://localhost:8080/meucontext/app1 e http://localhost:8080/meucontext/app2

Ou vc tem que dar um jeito de passar alguma parâmetro de uma aplicação para outra e refazer o login automaticamente na outra.

Se tiver alguma outra forma eu não conheço e gostaria muito de saber. Se vc descobrir posta para a gente a solução.

Abs.

Claudiney

P

Entendi perfeitamente sua sugestão ccalixto. Eu já havia pensado exatamente em colocar todas as aplicações dentro de um mesmo contexto. Porém ficaria impossível, já que existem inúmeras aplicações, e algumas delas com complexidade alta. Dae colocar como sendo uma pasta dentro do contexto principal dificultaria muito a manutenibilidade dos sistemas.

Atualmente, todos os sistemas estão escritos em jsp, e funcionam perfeitamente em relação à mudança de contexto. Nesse caso, foi utilizado o objeto request na página de login como parâmetro para uma classe que valida o usuário, sendo esta utilizada por todos os sistemas na sua respectiva página inicial. Tal objeto permanece inalterado quando o o action para o novo contexto é chamado, sendo os dados do usuário passados corretamente para a nova aplicação.

Dae eu nem preocupei muito no início da migração, pensando que poderia reutilizar essa lógica do objeto request, só que infelizmente não funcionou, retornando todos os parâmetros null na nova aplicação.
O que eu estou procurando realmente é uma maneira de passar estes benditos parâmetros para o novo contexto, como vc mesmo sugeriu (nesse caso usuário e senha seriam mais que sufucientes).

C

Criar um Filter para tratar isso, com a sua lógica atual não serviria?

A

Você pode me explicar o que seria isso?
E como iria ajudar?

Obrigado!

C

Um Filter, podemos dizer que ele faz um filtro das chamadas. Vc pode atribuir esse filter para ser acionado a todas páginas que terminem com .jsf por exemplo, ou então escolher outro padrão.

Vamos supor que vc crie uma classe filter para login e configure ela para interceptar todas as chamadas para páginas “.jsf”

Assim, toda vez que uma página .jsf for chamada o Filter interceptará a chamada, nesse filter vocês faz as validações necessárias (verifica se o usuário tem permissão de acesso) e autoria o acesso ou redireciona o usuário para uma tela de erro.

Eu pensei se vc não poderia ter um filter que possa interceptar quando vc quer sair de um contexto, ai esse filter cria alguma configuração, e outro filter que possa ser acionando no outro contexto que identifica que vc veio do outro sistema. Esse outro filter valida o usuário e define como logado.

Não sei se isso vai funcionar no seu caso. É uma idéia.

Abs.

F

Bom dia Amigos

Estou tendo o mesmo problema, preciso mudar de contexto em determinado momento e quando volto para co contexto anterior os valores de sessao estão nulos.

Alguem poderia me passar como seria este filter que o ccalixto sugeriu?

M
Amigo, o filtro que eu uso é o PhaseListener. Ele faz exatamente isso aí que o Calixto falou: é acionado a cada chamada de página jsf. Desta forma, você pode, por exemplo, criar uma variável de sessão que resgate os dados e não os perca quando da mudança de contexto. É mais ou menos assim:
public class LogadoListener implements PhaseListener {

    @SuppressWarnings("deprecation")
    @Override
    public void afterPhase(PhaseEvent event) {
            /*Aqui entra o código que será rodado ANTES do carregamento de qualquer página jsf. 
            Você pode, por exemplo, setar uma variável de sessão que guarda o seu contexto, para que, na mudança de contexto, você possa recuperar os dados anteriores: */
            FacesContext fc = event.getFacesContext();
            HttpSession httpSession = (HttpSession)fc.getExternalContext().getSession(true);
            HttpServletRequest request = (HttpServletRequest)fc.getExternalContext().getRequest();
            //Desta forma, cada vez que eu precisar acessar um dado deste contexto, o faço através de request.getParameter:
            String chave = request.getParameter("chave"); 
            //E cada vez que precisar guardar algo na sessão (que não será perdida, pois estamos no PhaseListener), utilizo um setAtribute:
            httpSession.setAttribute("usuario1", usuario1);
    }

    //Estes dois outros métodos são obrigatórios:
        @Override
	public void beforePhase(PhaseEvent event) {

	}

	@Override
	public PhaseId getPhaseId() {
		return PhaseId.RESTORE_VIEW;
	}
Dentro do método afterPhase, você pode colocar qualquer coisa que convenha fazer antes de carregar uma página, inclusive verificar se o usuário que está tentando acessar a url está com login válido. Isto é muito importante para evitar que alguém acesse uma página diretamente digitando a URL no browser, sem fazer o devido login.

Concluindo, para que o PhaseListener entre em ação, você precisa registrá-lo em seu faces-config.xml:

<lifecycle>
        <phase-listener>br.com.bb.listener.LogadoListener</phase-listener>
    </lifecycle>
F

Boa tarde marcuscarvalho1

Obrigado pela dica.

No meu caso eu estou utilizando struts1, entao devo configurar o struts-config ao inves do faces-config.xml e no xml ?

Para que eu possa entender melhor, quando a aplicaçao sair de um contexto o filtro ira recuperar a informaçao e quando entrar no outro contexto o filtro ira buscar novamente a informaçao.

Como que a informaçao de um contexto sera encaminhado para outro contexto.

P

Olá.
No meu caso resolvi implementando um Filtro Servlet, através da interface javax.servlet.Filter.
Basta declará-lo no web.xml e implementar o método doFilter, que já traz a solicitação enviada pelo browser através do parâmetro ServletRequest.

Filtro:

public class FiltroSeguranca implements Filter {

    public void init(FilterConfig config) throws ServletException {
    }

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpSession session = ((HttpServletRequest) req).getSession();

        Usuario usuario = (Usuario) session.getAttribute("usuarioSessao");
        Sistema sistema = (Sistema) session.getAttribute("sistemaSessao");
        if ((usuario == null) || (sistema == null)) {
            session.setAttribute("msg", "Você não está logado no sistema!");
            ((HttpServletResponse) res).sendRedirect("Sua_página_de_login");
        } else {
             // .....  lógica para verificar se o usuário possui permissão no sistema selecionado
            //se o usuário possuir acesso ao sistema selecionado, então processa.
            if (possuiAcesso)
               chain.doFilter(req, res);
            else{                
                ((HttpServletResponse) res).sendRedirect("Sua_página_de_login");
             }

    }

    public void destroy() {
    }
}

web.xml:

<filter>
      <filter-name>Filtro Seguranca</filter-name>
      <filter-class>filtro.FiltroSeguranca</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>Filtro Seguranca</filter-name>
      <url-pattern>/faces/*</url-pattern>
   </filter-mapping>

Em todos os sistemas o filtro é exatamente o mesmo, bastando também o(s) backingBean(s) de controle de usuário estarem devidamente declarados no faces-config.xml.

F

Ola amigos

Ainda nao sei como que o filtro ira me ajudar. Vou explicar o meu problema detalhadamente.

Tenho um EAR que se chama Corporativo.ear e outro EAR que se chama Terceiro.EAR

Eu faço login na pagina login.jsp que esta no contexto Corporativo.ear e ai faço uma consulta de serviços que o link para consulta chama a pagina servico,jsp do EAR Terceiro.EAR

O meu problema e que quando eu estou no contexto Corporativo.EAR eu tenho uma sessao que contem as informaçoes do usuario do tipo, sessionID, usuario.

Quando estou na pagina login.jsp do contexto Corporativo.EAR e sou direcionado para a pagina servico.jsp do Contexto Terceiro.EAR eu estou perdendo a sessao do contexto Corporativo.ear e esta sendo criado outra sessao no contexto Terceiro.EAR.

Eu preciso ter apenas a primeira sessao criada no contexto Corporativo.ear, por exemplo, quando eu entrar no contexto Corporativo.ear na pagina login.jsp sera criado a sessao 1000 e com usuario USER1000 e ao ser direcionado para a pagina servico.jsp do contexto Terceiro.ear quero continuar com a sessao 1000 e usuario USER1000 e tambem alem de levar a sessao e o usuario para outro contexto posso querer voltar para o contexto Corporativo para efetuar alguma consulta que esteja no contexto Corporativo.ear quero voltar com a mesma sessao inicial, sessao 1000 e usuario USER1000

Apenas como observacao, nao terei apenas a sessao e o usuario para transmitir de um contexto para outro, serao varias informacoes, sessao e usuario 'e apenas um exemplo.

Como utilizarei o filtro para recuperar a sessao sempre que trocar de contexto .

Desde ja, muito obrigado a quem puder me ajudar.

M

Farzac,

já que você está fazendo em Struts, esse código aí em cima do companheiro Puro Osso resolve seu problema. Entenda o seguinte: cada vez que qualquer das páginas carregar esse código do método doFilter vai entrar em ação. Se você pretente, ao carregamento de uma página, guardar ou mudar um dado qualquer (por exemplo, as informações do USER1000), basta usar:

session.setAttribute("user", "aqui vem a informação, ou mesmo o objeto que você pode criar com todas as informações que vai precisar");

E cada vez que precisar recuperar esta informação (que não se perderá com a mudança de contexto), basta usar:

(/*aqui faça o cast do seu objeto*/)session.getAtribute("user");

ou ainda:

req.getParameter("user");
F

Ola marcuscarvalho1

Por exemplo, terei entao 2 paginas de filtro, 1 no contexto Corporativo.EAR e outra no contexto Terceiro.EAR.

Quando ser encaminhado para uma pagina do Corporativo.EAR, o filtro ira recuperar a informacao que preciso e guardara em um objeto de sessao e quando navegar para pagina de outro contexto, o outro filtro ira recupera a sessao do contexto Corporativo.EAR e salvara uma outra sessao com as mesmas informaçao da sessao do contexto Corporativo.EAR no contexto Terceiro.EAR

Se for isso mesmo, acho que estarei economizando muitas linhas de implementaçao.

Desde ja, muito obrigado a todos.

Criado 8 de maio de 2008
Ultima resposta 30 de jun. de 2011
Respostas 15
Participantes 6