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 
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.