VRaptor Adicionar/Remover @Component na Session

Boa tarde,

Estou desenvolvendo uma aplicação de testes com o VRaptor, e estou sentindo um pouco de falta do ViewScope do JSF, mas fora o isso esse VRaptor é TOP.
Bom pra suprir essa falta em alguns casos estou utilizando o @Component e o @SessionScoped pra jogar alguns componentes na sessão, e estou com algumas dúvidas se alguem puder me ajudar, valeu.

  • existe maneira de definir exatamente o nome que eu quero para a KEY do Map de atributos da Session? Eu reparei que os atributos vão com o mesmo nome da Classe, mas existe a possibilidade de eu trocar esse nome, algo parecido com:
@SessionScoped(name="xpto");//Sei que isso não existe mas é só pra exemplo

outra dúvida:
Em determinados momentos eu preciso remover alguns componentes la da sessão sem inativar a sessão em si.
Eu estou fazendo o simples:

request.getSession().removeAttribute("NOME_DA_CLASSE_DO_COMPONENTE");

Eu posso fazer isso, ou tem outro jeito mais certo de fazer?
Eu reparei que junto com o componente é adicionado outro atributo na session chamado:

org.springframework.web.context.request.ServletRequestAttributes.DESTRUCTION_CALLBACK.NOME_DA_CLASSE

Eu preciso chamar o Destroy na minha classe antes de remover da sessão?

Valeu pela ajuda galera.

uma saída pra isso é usar um cara @SessionScoped só pra gerenciar os caras na sessão do lado do servidor… daí ele recebe a httpSession no construtor e inclui e exclui os objetos da sessão.

O ViewScope do JSF funciona pq a cada request o estado inteiro da página é enviado pro servidor… Sem fazer isso, se o cara abrir duas abas do sistema, vai misturar a sessão, e não tem um jeito muito fácil de saber qual é a aba. Só se passar algum parâmetro em toda a requisição (dá pra tentar fazer via javascript interceptando todos os links e forms)

Lucas, valeu.

É exatamente isso que eu estou fazendo agora usando o @SessionScoped, mas minha dúvida é como retirar esse Objeto adicionado a sessão:
Posso fazer o trivial, ou existe algum outro jeito mais correto de retirar coisas da Session:

request.getSession().removeAttribute("NOME_DA_CLASSE"); //Nome da classe que está com @SessionScoped

E mais uma dúvida tem como eu manipular o nome com que o objeto vai ser adicionado na Session?

tava pensando em algo mais assim:

@SessionScoped
@Component
public class MinhaClasseComQQerNome {
    // recebe HttpSession no construtor

    public Classe criaClasse( ... ) {
         Classe classe = //...

         session.setAttribute("classe", classe);
    }

    public void removeClasse() {
        session.removeAttribute("classe");
    }
}

Ah entendi, legal, uma espécie de Factory adicionada na Session. Bem interessante, vou tentar assim.

Lucas a ideia ainda é a mesma para o vraptor 3? preciso fazer algo muito semelhante a isso só que com uma lista, e estou pensando em fazer o seguinte.

@SessionScoped
@Component
public class MinhaClasseComQQerNome {
private httpsession…
public MinhaClasseComQQerNome(HttpSession) {
recebe a session
}

public Classe criaClasse( ... ) {  
     Lista l1 = new ArrayList...  
     session.setAttribute("classe", l1);
}  

public void removeClasse() {  
    session.removeAttribute("classe");  
}  

}

isso funciona normalmente :wink:

está acusando o seguinte erro:

se vc tá fazendo um session.invalidate() vc não pode mexer com a sessão mesmo.

bem, deixa eu ser mais especifico, hoje, se eu quero setar algo na sessao, eu faço o seguinte, eu vou lá e coloco session.setAttribute(“nome”, objeto). e pra remover vou lá e .removeAttribute…

quando eu inicio meu tomcat pelo que eu entendi o vraptor inicia esse atributo empresas na sessão já pra mim, agora suponha que eu queira fazer o removeAttribute desse empresas como faria? pq da forma que estou fazendo abaixo nao está funcionando, e outra depois de remover como eu faria para inserir novamente?

@Component
@SessionScoped
public class EmpresasWeb {
	
	private final HttpSession session;
	private List<Empresa> empresas = new ArrayList<Empresa>();
	
	public EmpresasWeb(HttpSession session) {
		this.session = session;
	}
	
	public void inserirEmpresaNaSessao() {
		this.session.setAttribute("empresas", empresas);
	}
	
	public void removerEmpresaDaSessao() {
		this.session.removeAttribute("empresas");
	}

	public List<Empresa> getEmpresas() {
		return empresas;
	}

	public void setEmpresas(List<Empresa> empresas) {
		this.empresas = empresas;
	}
	
	public void limpaLista() {
		this.empresas.clear();
	}
	
}

ou seja, como eu pego o request.getSession().getAttribute( ? );

dessa private List empresas = new ArrayList();

ps: preciso passar o empresas como atributo pq estou setando objetos nessa lista.

nas jsps vc consegue pegar pelo nome: ${empresas}

vc só não vai conseguir remover o EmpresasWeb da sessão… mas o atributo vai funcionar normalmente

eu não queria remover o EmpresaWeb da sessao, eu queria remover e adicionar os atributos dele no momento que eu quiser, pq vou precisar, na verdade é para simular um @viewScope digamos assim, que preciso que o atributo lista dessa empresaweb fique na sessao enquanto o usuario estiver em determinada pagina, ja criei o interceptor para isso e está funcionando corretamente, mais nao consigo remover o atributo list da sessao, de modo que quando muda de pagina as listas que foram persistidas ainda continuam pq o atributo ainda se encontra na sessao. queria remover e adicionar o atributo no momento em que eu quisesse.

se eu usar um @SessionScope e tentar efetuar um setAttribute ele está dando invalidate ou expirando a sessao.

não tem nenhuma outra parte do sistema chamando o invalidate? o VRaptor não chama invalidate em nenhum momento.

não, não possui.

o que eu fiz foi o seguinte, criei um interceptor coloquei

if(session.getAttribute(“empresasWeb”) != null) {
session.removeAttribute(“empresasWeb”);
}

e está destruindo sim, so que por algum motivo ele apos destruir o vraptor axo que cria novamente, de solucionar o problema da lista soluciona, o problema é que sempre vai ter o objeto na sessao, e não queria isso, queria ter o objeto na sessao (pelo menos esse) somente quando eu quisesse.

toda vez que vc receber esse EmpresasWeb no construtor o VRaptor vai recriar o objeto sim, pq ele precisa fazer isso.

é só vc colocar isso só no controller das páginas que vão precisar dele.

a ideia é essa tipo, se nao estiver no controller, destrua o objeto da sessao e quando eu acessar a pagina do controller que possui essa empresaweb no construtor ele cria novamente.

porem eu estou fazendo o seguinte:

[code] public void intercept(InterceptorStack stack, ResourceMethod method,
Object resourceInstance) throws InterceptionException {

	System.out.println(session.getAttribute("empresasWeb"));
	//logica antes
	stack.next(method, resourceInstance);
	session.removeAttribute("empresasWeb");
	System.out.println(session.getAttribute("empresasWeb"));
	//logica depois

}[/code]

isso somente na minha index/index, ou seja no controller index, e no IndexController nao possuo EmpresaWeb, e toda vez está vindo o objeto instanciado, depois removo e depois null;

se eu der f5 ele novamente me mostra o objeto instanciado, ai remove e depois null.

ou seja depois da primeira vez, quando eu desse f5 era pra vir null e null

e somente quando eu estivesse no UsuarioController (quem possui empresasWeb no construtor) é que deveria vir objeto e depois null.

Se você quer fazer isso, mude o EmpresasWeb para @RequestScoped, daí vc não precisa desse interceptor.

se eu mudar para request scope, toda vez no usuario controller quando eu chamar o metodo

@Post
	@Path("/usuario/addEmpresa/{codigoExterno}")
	public void addEmpresa(int codigoExterno) {
		if(codigoExterno != 0 ) {
			Empresa emp = this.empresaRep.findEmpresaById(codigoExterno);
			this.empresas.getEmpresas().add(emp);
		}
		result.use(Results.json()).withoutRoot().from(empresas.getEmpresas()).serialize();
	}

ele em vez de permanecer com a lista ele sempre vai ficar com o ultimo adicionado, pq quando ele chama uma requisiçao para o addEmpresa ele vai criar uma nova lista. pq a lista será do tipo RequestScope

a ideia é que enquanto eu estiver no UsuarioController/formulario ou melhor, enquanto estiver no UsuarioController, essa lista exista, e quando sair do USuarioController essa lista saia, obs: essa lista nao está sendo salva no banco quando faz o addEmpresa, é somente quando salvar o usuario vou fazer o segunite, usuario.setEmpresas(aqui vou passar a lista.)

é só aproveitar a lista que tá na session… só criar se ela não existir

mais se eu colocar

@RequestScope em empresasWeb eu nao vou ter lista na session lucas.