Vraptor 3 Duvidas

Boa tarde pessoal, tenho algumas duvidas sobre o vraptor, vamos lá:
Bom quando eu utilizo a anotação @SessionScoped, seria para que o objeto ficasse disponível em toda a session?
Como faço para pegar esse objeto da session em um interceptor?
Exemplo: usuário quando loga no sistema, quero que ele fique disponível em toda a sessão e só deixe de existir quando o usuário fizer o logoff, preciso disso para ter rastreabilidade das ações do usuário, como por exemplo quem foi o ultimo a atualizar determinada informação, etc.

Não tenho muita ideia de como fazer isso com o Vraptor, mas comecei a fazer umas classe:

Classe do Usuario


import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.SessionScoped;

@Component
@SessionScoped
public class Usuario {
	
	private String re;
	private String senha;
	private String nome;
	private int tipo;
		
	public String getRe() {
		return re;
	}
	public void setRe(String re) {
		this.re = re;
	}
	public String getSenha() {
		return senha;
	}
	public void setSenha(String senha) {
		this.senha = senha;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public int getTipo() {
		return tipo;
	}
	public void setTipo(int tipo) {
		this.tipo = tipo;
	}
	
	public boolean isNull() {
		if (this.re.equals("")) {
			return true;
		} else {
			return false;
		}
	}

Classe LoginController

import javax.servlet.http.HttpSession;

import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.view.Results;
import br.com.cmc.dao.UsuarioDao;
import br.com.cmc.jdbc.ConnectionFactory;
import br.com.cmc.modelo.Usuario;

@Resource
public class LoginController {
	
	private final HttpSession session;
	private final ConnectionFactory conn;
	private final Result result;
		
	public LoginController(HttpSession session, ConnectionFactory conn, Result result) {
		super();
		this.session = session;
		this.conn = conn;
		this.result = result;		
	}

	@Path("/logar")
	public void logar (Usuario usuario) {
		
		usuario = new UsuarioDao(this.conn.getConnectionMySql(), usuario).login();
		
		if (usuario.isNull()) {
			
			this.result.redirectTo(IndexController.class).root();
			this.result.include("messag", "Usuario ou senha incorreta");
			
		}else{
			
			this.result.include("userLogado", usuario);
			//this.result.include("conn", this.conn.getConnectionMySql());
			
			if (usuario.getTipo() == 1){
				this.result.forwardTo(AdminController.class).admin();
			} else if (usuario.getTipo() == 2){
				this.result.forwardTo(AtendController.class).atendente();
			}
		}		

	}
	
	@Path("/logoff")
	public void logOff() {
		this.session.invalidate();
		this.result.use(Results.logic()).redirectTo(IndexController.class).root();		
	}

Interceptor: Aqui gostaria de pegar o objeto usuário e verificar se existe, ai se existir continua, caso não retornar para o login, mas esse interceptor no pode intercepitar a minha primeira pagina que é a de login.

import javax.servlet.http.HttpSession;

import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.com.caelum.vraptor.resource.ResourceMethod;

@Intercepts
@RequestScoped
public class AcessoIntercept implements Interceptor {
	
	private final HttpSession session;
	
	public AcessoIntercept(HttpSession session) {
		this.session = session;
	}

	public boolean accepts(ResourceMethod arg0) {		
		return true;		
	}

	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
					
		stack.next(method, resourceInstance);
		
	}

Obrigado pessoal

Pra você deixar um objeto na sessão do servidor com o vraptor é sim ples, basta você anotá-lo com o @SessionScoped.
Você poderia ter uma classe UsuarioSessao que vai ter um Usuario + - assim:

@Component  
@SessionScoped
public class UsuarioSessao {
    private Usuario usuario;
   ....
}

e os seu usuário, seria uma entidade normal… sem essas anotações. Ex:

public class Usurio{
    private Long id;
    private String nome;
    //...
}

Agora no seu controller você precisa add o seu usuário a esse objeto que estará na sessão do seu servidor, você pode pegá-lo apenas pedindo para o vrapotr pelo controller Ex:

@Resource  
public class LoginController {  
    private Result result;  
    private UsuarioSessao session;      
    public LoginController(UsuarioSessao session, Result result) {    
        this.session = session;  
        this.result = result;         
    }  
  
    @Path("/logar")  
    public void logar (Usuario usuario) {  
        if(tudoOk()){
            session.setUser(usuario);
        }
    }

certo?

flw

Legal Kadu, vou fazer essas alterações e já posto no forum, agora como eu pegaria o usuário que está na sessão dentro do interceptor, teria que utilizar algo tipo:

vc teria algum exemplo?

Valew

Perdão tinha esquecido dessa parte, mas basta você pedir o objeto para o vraptor:

@Intercepts  
@RequestScoped  
public class AcessoIntercept implements Interceptor {  
      
    private UsuarioSession session;  
      
    public AcessoIntercept(UsuarioSession session) {  
        this.session = session;  
    } 

public boolean accepts(ResourceMethod arg0) {         
        return true;          
    }  
  
    public void intercept(InterceptorStack stack, ResourceMethod method,  
            Object resourceInstance) throws InterceptionException {  
                     Usuario usuario =  session.getUsuario();
        stack.next(method, resourceInstance);  
          
    }  
}

Então Kadu, fiz a alteração do Interceptor, só que está interceptando a minha primeira pagina de login, ai acaba dando erro, como eu poderia fazer para o interceptor pegar todas as requisições menos a primeira da pagina de login?

Interceptor:

import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.cmc.controlador.LoginController;
import br.com.cmc.session.UsuarioSession;

@Intercepts
@RequestScoped
public class AcessoIntercept implements Interceptor {
	
	private final UsuarioSession userSession;
	private final Result result;

	public AcessoIntercept(UsuarioSession userSession, Result result) {
		this.userSession = userSession;
		this.result = result;
	}

	public boolean accepts(ResourceMethod arg0) {		
		return true;		
	}

	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
		
		if (userSession.isValido()){
			stack.next(method, resourceInstance);
		} else {
			result.redirectTo(LoginController.class).logOff();
		}
		
	}

}

Mas uma vez obrigado

Voce cria uma annotation Login e anota o seu método com ela
o interceptor só vai validar quem tiver com ela…

	@Override
	public boolean accepts(ResourceMethod method) {
		return method.containsAnnotation(Login.class);
	}

Obrigado Kadu pela dica, pesquisei e encontrei um link com um exemplo completo
http://wbotelhos.com/2010/04/07/controle-de-login-com-vraptor-3

Vou seguir o exemplo ai depois posto no forum.

Valew

Boa, esse exemplo encaixa certinho pra você.

Kadu, fiz as alterações, mas parece que o UsuarioSession está chegando null no interceptor

UsuarioSession

@Component
@SessionScoped
public class UsuarioSession {
	
	private Usuario usuario;

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}
	
	public boolean isValido(){
		return usuario != null;
	}	

}

LoginController

@Resource
public class LoginController {
	
	private final HttpSession session;
	private final ConnectionFactory conn;
	private final Result result;
	private UsuarioSession userSession;

	public LoginController(HttpSession session, ConnectionFactory conn,
			Result result, UsuarioSession userSession) {
		super();
		this.session = session;
		this.conn = conn;
		this.result = result;
		this.userSession = userSession;
	}

	@Path("/logar")
	public void logar (Usuario usuario) {
		
		this.userSession.setUsuario(new UsuarioDao(this.conn.getConnectionMySql(), usuario).login());
		
		if (!this.userSession.isValido()) {
			
			this.result.redirectTo(IndexController.class).root();
			this.result.include("messag", "Usuario ou senha incorreta");
			
		}else{
			
			//AQUI IMPRIME O NOME
			System.out.println(userSession.getUsuario().getNome());
			
		}
				
	}

Interceptor

@Intercepts
@RequestScoped
public class AcessoIntercept implements Interceptor {
	
	//private final HttpSession session;
	private UsuarioSession userSession;
	private final Result result;

	public AcessoIntercept(UsuarioSession userSession,
			Result result) {
		this.userSession = userSession;
		this.result = result;
	}

	public boolean accepts(ResourceMethod method) {		
		return !(method.getMethod().isAnnotationPresent(AcessoLivre.class) ||
				method.getResource().getType().isAnnotationPresent(AcessoLivre.class));		
	}

	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
		
		/* verifica objetos na sessão
		System.err.println("Session :" + session.getId());
		Enumeration<String> e = session.getAttributeNames();
		
		while (e.hasMoreElements()){
			System.err.println(session.getAttribute(e.nextElement()));
			System.err.println();
		}
		
		stack.next(method, resourceInstance);
		*/		
		
                //AQUI DA O ERRO
		System.out.println(userSession.getUsuario().getNome());
		stack.next(method, resourceInstance);
		
		/*
		if (userSession.isValido()){
			stack.next(method, resourceInstance);
		} else {
			result.redirectTo(LoginController.class).logOff();
		}
		*/
	}

}

Erro

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error that prevented it from fulfilling this request.

exception

java.lang.NullPointerException
	br.com.cmc.interceptor.AcessoIntercept.intercept(AcessoIntercept.java:48)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.37 logs.

Apache Tomcat/7.0.37

vc pode me dizer onde cai? no else ou no if?

if (!this.userSession.isValido()) {  
              
            this.result.redirectTo(IndexController.class).root();  
            this.result.include("messag", "Usuario ou senha incorreta");  
              
        }else{  
              
            //AQUI IMPRIME O NOME  
            System.out.println(userSession.getUsuario().getNome());  
              
        }  

Verifica se isso, está retornando null.

new UsuarioDao(this.conn.getConnectionMySql(), usuario).login()

Agora que eu vi, você esqueceu da anotação no método login

@AcessoLivre
@Path("/logar")  
    public void logar (Usuario usuario) {  
          
        this.userSession.setUsuario(new UsuarioDao(this.conn.getConnectionMySql(), usuario).login());  
          
        if (!this.userSession.isValido()) {  
              
            this.result.redirectTo(IndexController.class).root();  
            this.result.include("messag", "Usuario ou senha incorreta");  
              
        }else{  
              
            //AQUI IMPRIME O NOME  
            System.out.println(userSession.getUsuario().getNome());  
              
        }  
                  
    }  

Aqui entra no else

[quote]
Verifica se isso, está retornando null.

new UsuarioDao(this.conn.getConnectionMySql(), usuario).login() [/quote]
Aqui não retorna null, ele retorna o usuário completo.

Então Kadu, o método logar, só é chamado quando o usuário informa os dados para efetuar o login, eu fiz o teste e anotei o método com @AcessoLivre, realmente o interceptor não ira intervir, mas neste caso creio que ele teria que interceptar, para não ter o problema do usuário chamar o método direto pela url “endereco/logar” ele só chamaria o método através da tela de login.

Bom o estranho é que mesmo assim o UsuarioSession chega null no interceptor, enquanto em outras classes e até nos jsp ele retorna o usuário completo.

[code]

OLA   ${usuarioSession.usuario.nome}

ESTA É A PAGINA INICIAL DO ADMINISTRADOR

" >SAIR [/code]

tenta ver se o usuário tá chegando mesmo no usuarioSession:

@Component
@SessionScoped
public class UsuarioSession {
   //...

   public void setUsuario(Usuario usuario) {
       System.out.println(usuario);
       this.usuario = usuario;
   }
}

Então Lucas, o usuário chega normalmente no usuarioSession, fiz conforme vc disse, e imprimiu

br.com.cmc.modelo.Usuario@55c656b4

O usuarioSession esta chegando com informação em qualquer outra classe e jsp, só do interceptor que não, no interceptor ele chega com o atributo usuario null.

mas isso acontece mesmo depois do login?

[quote=AndersonQuinteiro]Então Lucas, o usuário chega normalmente no usuarioSession, fiz conforme vc disse, e imprimiu

br.com.cmc.modelo.Usuario@55c656b4

O usuarioSession esta chegando com informação em qualquer outra classe e jsp, só do interceptor que não, no interceptor ele chega com o atributo usuario null.
[/quote]

Mas como ele consegue chegar em outra classe ou jsp sendo que daria NullPointer no interceptor?

Sim, acontece mesmo depois de ter feito o login.
Estou fazendo +/- assim:

Quando acesso o sistema, o meu index é o formulário de login, o método root() esta com a anotação @AcessoLivre, ai efetuo o login quando estou com o interceptor inativo (accepts retornando false) então verifico o ussuarioSession na classe ou no jsp, então ele está lá.

Exemplo da classe que verifico o usuarioSession.

[code]
@Resource
public class AdminController {

public UsuarioSession usuarioSession;

public AdminController(UsuarioSession usuarioSession) {
	super();
	this.usuarioSession = usuarioSession;
}


@Path("/admin")
public void admin(){
	
	System.out.println(usuarioSession.getUsuario().getNome());
	
}

}[/code]

Exemplo do jsp que verifico o usuarioSession

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Titulo</title>
</head>
<body>
OLA &nbsp; ${usuarioSession.usuario.nome} <br>
<br>
ESTA É A PAGINA INICIAL DO ADMINISTRADOR
<br>
<a href="<c:url value="/logoff" />" >SAIR</a>
</body>
</html>

Até aqui funciona perfeitamente, ai quando eu coloco o interceptor, começa o problema, verifico o usuarioSession e ele está null, já refiz o interceptor 3 vezes, mas nenhum sucesso rsrs.

Interceptor que estou usando

@Intercepts
public class RestritoInterceptor implements Interceptor{
	
	private UsuarioSession usuarioSession;
		
	public RestritoInterceptor(UsuarioSession usuarioSession) {
		super();
		this.usuarioSession = usuarioSession;
	}

	public boolean accepts(ResourceMethod method) {
		
		return !(method.getMethod().isAnnotationPresent(AcessoLivre.class) || 
				method.getResource().getType().isAnnotationPresent(AcessoLivre.class));
		
		//return false;
	}

	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
		
		System.out.println(usuarioSession.getUsuario().getNome());
		stack.next(method, resourceInstance);		
				
	}	
	
}

Erro gerado

SEVERE: Servlet.service() for servlet [default] in context with path [/cmc] threw exception
java.lang.NullPointerException
	at br.com.cmc.interceptor.RestritoInterceptor.intercept(RestritoInterceptor.java:32)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

Não estou conseguindo enxergar onde estou errando rs.

troca isso:

public void intercept(InterceptorStack stack, ResourceMethod method,  
            Object resourceInstance) throws InterceptionException {  
        if (usuarioSession.getUsuario() != null) {
           System.out.println(usuarioSession.getUsuario().getNome());  
        }
        stack.next(method, resourceInstance);         
                  
    } 

e veja se ele passa por aí depois do login.

Olha só quando eu altero e coloco primeiro o stack e depois o System.err.println o problema não acontece, ai imprime o nome do usuário corretamente.

	public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {
		
		stack.next(method, resourceInstance);
		System.err.println(usuarioSession.getUsuario().getNome());
				
				
	}

Quando que o Interceptor é chamado? na ida da requisição ou na resposta do servidor?
Por que se for na ida, talvez seja ai o erro, ele ainda não realizou o login. poxa rsrsrsrs

[quote=Lucas Cavalcanti]troca isso:

public void intercept(InterceptorStack stack, ResourceMethod method,  
            Object resourceInstance) throws InterceptionException {  
        if (usuarioSession.getUsuario() != null) {
           System.out.println(usuarioSession.getUsuario().getNome());  
        }
        stack.next(method, resourceInstance);         
                  
    } 

e veja se ele passa por aí depois do login.[/quote]

então Lucas, acabei de ver seu post, fiz o que disse, e não entra no if