VRaptor3 - uso de objetos session/application

24 respostas
A

Olá pessoal,

seguem abaixo 2 dúvidas:

1. num servlet para acessar um objeto session podemos usar, por exemplo,
É possível fazer algo análogo a isto em num controller do Vraptor3 ??

     Obs.: Já consegui acessar um objeto session injetado automaticamente, mas quero fazer isto programaticamente.



     2. É possível fazer algo análogo ao citado acima num controller do Vraptor3 para objetos application ??

Obrigado

24 Respostas

Lucas_Cavalcanti

o jeito mais simples de fazer isso é criando uma classe:

@Component
@SessionScoped
public class UsuarioLogado {
     private Usuario usuario;
     //getter e setter... ou login e logout se vc preferir
}

e receber essa classe no construtor dos seus controllers que precisarem usar o usuario logado

nos jsps vc pode acessar o usuario na sessão por:
${usuarioLogado.usuario}

Pra fazer isso para application é só trocar a anotação @SessionScoped por @ApplicationScoped

Dê uma olhada na documentação do vraptor para mais detalhes:
http://vraptor.caelum.com.br/documentacao/componentes/
ou baixe a apostila da caelum:
http://www.caelum.com.br/curso/fj-28-vraptor-hibernate-ajax/

Fabio_Kym_Nascimento

Lucas, aproveitando o ensejo da duvida, vc sabe como o vraptor passa essa variavel usuarioLogado pro jsps?

Pq aqui eu nao to conseguindo testar a variavel no jsp, é como se ela não tivesse sendo passada pra la, teria que ficar adicionando ela?

Se eu no metodo do controller do um result.include no usuarioLogado blz, se eu não faço isso ela não existe no jsp :confused:

G

Fabio, eu já respondi lá no seu outro tópico. Resumo: se você tem uma classe chamada UsuarioLogado o vraptor exporta a variável para o JSP como usuarioLogado, ou seja, o nome da classe em camel-case.

Abraços

A

Oi Lucas,

este jeito mais simples que você explicou foi o jeito que eu já havia feito, via injeção.

A minha dúvida era sobre o jeito mais complicado, ou seja, acessar o objeto de escopo session programaticamente.

Como se faz isto programaticamente ??

abçs

G
asdias:
Oi Lucas,

este jeito mais simples que você explicou foi o jeito que eu já havia feito, via injeção.

A minha dúvida era sobre o jeito mais complicado, ou seja, acessar o objeto de escopo session programaticamente.

Como se faz isto programaticamente ??

abçs

Basta injetar na sua classe o objeto HttpSession.

public class MinhaClasse {
    private final HttpSession session;

    public MinhaClasse(HttpSession session) {
        this.session = session;
    }

    public void foo() {
        Usuario usuario = (Usuario) session.getAttribute("usuarioLogado");  
    }
}
Lucas_Cavalcanti

asdias, não entendi o que vc quer dizer com programaticamente… dá um exemplo do que vc quer fazer, por favor?

G

Acho que a intenção dele era programaticamente = manualmente.

A

olá pessoal,

sei como acessar a session via injeção, pelo construtor.

A minha dúvida é: Como fazer isto manualmente, ou seja, acessar no meio do código do controller sem ter que injetar pelo construtor ??

ex.:

ou

Em PHP4 é assim:

abçs

G

asdias, eu já te respondi!!!

você precisa primeiro injetar o HttpSession no seu construtor, e depois usar-lo a vontade. Você precisa pelo menos injetar a session pelo construtor. No vraptor não tem como você ter a session assim por mágina, apenas assim ou injetando direto o objeto anotado com SessionScoped no construtor. Um dos dois.

public MyClass {
  private final HttpSession session;

  public MyClass(HttpSession session) {
    this.session = session;
  }

  public void foo() {
    Usuario u = session.getAttribute("usuario");
  }
}
Lucas_Cavalcanti

Não é recomendado fazer isso… Isso é uma péssima prática de programação e deixa seu código procedural e não testável e mtas outras coisas…

Não se importe de receber coisas no construtor, pq não vai ser vc que vai dar new nas classes, vai ser o VRaptor… sendo radical, vc não deveria dar new em nenhuma classe qdo estiver programando com o vraptor, deixe isso para a injeção de dependências

A

Olá pessoal,

ok, então não dá para acessar manualmente a session num controller vRaptor, semelhante ao que fazemos com servlets.
Isto só é possível via injeção.

A questão é que tenho uma controller com 10 métodos e só 1 deles usa objetos da session.
Vou ter que sempre injetar via construtor, mesmo que o método chamado não precise de session.

Vou então implementar lazy dependency injection.

Obrigado pela ajuda.

Abçs.

G

O gasto que você terá com uma lazy-http-session é maior que você injetar e não usar. Afinal a http-session já existe e está criada, no caso o vraptor apenas injeta ela a você. Ou seja, você injetando ou não já terá ela ocupando espaço em memória.

Outro dia diz uns testes no meu projeto, que ao invés de eu injetar o EJB no construtor fiz um esquema para injetar um lazy-EJB. O tempo gasto para gerar um proxy foi maior do que fazer sempre o lookup do EJB remoto.

Abraços

Lucas_Cavalcanti

geralmente vc não deveria mexer com o HttpSession, nem HttpServlet(Request|Response) dentro dos seus controllers… não tem outro jeito melhor de fazer isso que vc quer? por exemplo criando um componente session scoped?

Lucas_Cavalcanti

em que caso isso faz sentido? não consigo pensar em nenhum…

e no caso de um componente de mais de um escopo, como eu digo qual escopo eu quero qdo receber ele no construtor?

Lucas_Cavalcanti

geralmente as entidades não serão componentes, pois elas virão do banco geralmente… Não tem nenhum jeito de falar: o meu component Produto vai ser esse que eu baixei do banco agora… todo componente é instanciado e gerenciado pelo VRaptor, vc não tem como trocar a instancia do componente sem fazer uma gambiarra grande…

Na prática o que eu faria é criar outra classe que seria responsável por guardar esses produtos para comparação… e essa outra classe seria session scoped

Lucas_Cavalcanti

tipo fazer um result.include que inclui na sessão, certo?

de qqer forma, colocar um método assim só deixaria o objeto disponível nas jsps… não daria pra colocar ele como dependências de outras classes… pelo menos não faria mto sentido…

Lucas_Cavalcanti

mas vc quer depois de adicionar na session receber o objeto como dependência nas outras classes?

Lucas_Cavalcanti

é bom sempre fugir de variáveis globais… isso dificulta o design e a testabilidade das classes do sistema…

encapsular o objeto numa classe session scoped é melhor do que colocar direto no HttpSession…

vc pode abrir uma issue para fazer isso por favor? se possível em inglês: http://github.com/caelum/vraptor/issues

seufagner

Lucas

Porque um componente/entidade pode estar apenas em um tipo de escopo?

Há momentos, por exemplo, que eu posso querer utilizá-la em @SessionScoped e em outros em @PrototypeScoped, porém configurando na própria classe eu só posso utilizar em um tipo.

seufagner

Pense na seguinte estória:

Estou num site de ecommerce e desejo comparar dois produtos, ou mais. Então eu vou filtrar alguns de meu interesse.
Ao listar eu seleciono um Macbook e digo q ele é meu primeiro produto para comparação.

O Controller guarda este no escopo de sessao para que possa efetuar outras buscas atrás do outro produto que será comparado.

Efetuo outra busca para encontrar o Sony Vaio e então comparar com o Macbook.

  1. A lista de produtos está no escopo request.
  2. Meu Produto MacBook deveria estar na sessão, mas já marquei como @RequestScoped.
  3. O Sony vaio também é request.

Uma solução seria anotando o atributo do controller, não a própria entidade. O que você acha?

seufagner

Perfeito.

O que sugeri foi criar um mecanismo no VRaptor para, em determinado momento, guardar coisas que foram passadas como parâmetro na sessão.

Eu me referi justamente ao fato de ter que criar uma classe, anotar com session scoped, e entao conseguir guardar algo no escopo informado. Criar uma classe só pra isso?

Seria interessante ter uma forma de indicar ao VRaptor que (por baixo dos panos ele usa o HttpSession) deseja guardar algo na sessao ou no contexto da aplicacao.

seufagner

A minha ideia era usar o proprio esquema de @SessionScoped do vraptor, porem por instancia. Ele passaria a gerenciar a q citei com este escopo programaticamente.

Algo como
result.include(sessionScoped()).add(“blabla”,obj);

ou para manter a linha ja existente

result.include(“blabla”,obj).in(sessionScope());

seufagner

eu entendo que isso mudaria a forma como se pensa o @SessionScoped (que é por tipo e não por instância), o que de qualquer forma ficaria estranho, parecendo variavel global, muito ruim…

de repente poderia fazer com que este objeto seja recuperado atraves de algum cara que é utilizado apenas nos Controllers, tal qual o Result e o Validator. restringindo o acesso pelo conceito, sacou? ainda não vi ninguem usando estes citados nas classes de um service layer, tampouco num dao. Aí seria erro/má pratica de programacao…

seufagner

beleza… farei isso… pois vou precisar, inclusive no sistema que estou desenvolvendo…

Criado 26 de janeiro de 2010
Ultima resposta 31 de jan. de 2010
Respostas 24
Participantes 5