[Resolvido] Exibicao do objeto na Session com VRaptor3

17 respostas
jurado

Seguindo a documentacao, encapsulei meu objeto de sessão em um wrapper com @SessionScoped. Estou passando-o no construtor para um controller e recupero-o com sucesso pelo bom e velho System.out.println(). Porém quero exibir um valor dele na view. Como faco isso?

Ele é incluido na sessao desta forma:

@Post public void logar(Usuario usuario) { this.usuario = this.daoFactory.getUsuarioDao() .obtemAutenticado(usuario); if (this.usuario == null) { // aqui vai meu objeto de sessao this.usuarioAutenticado.setUsuarioAutenticado(null); result.use(Results.logic()).redirectTo(AdminController.class) .login(); } else { this.usuarioAutenticado.setUsuarioAutenticado(this.usuario); result.use(Results.logic()).redirectTo(MenuController.class).menu(); } }

Recupero-o no meu ‘menu’ sem problemas:

public MenuController(UsuarioAutenticadoSession usuarioAutenticado) {
		super();
		this.usuarioAutenticado = usuarioAutenticado;
		System.out.println(this.usuarioAutenticado.getUsuarioAutenticado()
				.getLogin());
	}

Só que eu quero exibi-lo no jsp. Estou fazendo assim, sem sucesso:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!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>Insert title here</title>
</head>
<body>
<h1>Funcionando!<input type="text"
	name="usuarioautenticado.usuario.login"
	value="${usuarioAutenticado.usuario.login}" /></h1>
</body>
</html>

Este é o Wrapper:

@Component
@SessionScoped
public class UsuarioAutenticadoSession implements Serializable {
	private static final long serialVersionUID = 1L;
	private Usuario usuarioAutenticado;

	public Usuario getUsuarioAutenticado() {
		return usuarioAutenticado;
	}

	public void setUsuarioAutenticado(Usuario usuarioAutenticado) {
		this.usuarioAutenticado = usuarioAutenticado;
	}
}

pois, o usuarioautenticado possui o getter no MenuController. Já tentei com outros cases para ${usuarioAutenticado.usuario.login}, ${usuarioautenticado.usuario.login}, etc mas nada feito… Ele vem vazio… Alguma ideia?

17 Respostas

jurado

Resolvido!

Acrescentei o usuarioAutenticado pra view assim:

public void menu() {
		this.result.include("usuarioAutenticado", this.usuarioAutenticado);
	}

E obtive-o na view assim:

<h1>Bem vindo, ${usuarioAutenticado.usuarioAutenticado.login}!</h1>

Uma outra forma foi usar o proprio getter do usuarioAutenticadoSession, sem ter q manipular o result:

public UsuarioAutenticadoSession getUsuarioAutenticado() {
		return this.usuarioAutenticado;
	}
<h1>Bem vindo, ${usuarioAutenticadoSession.usuarioAutenticado.login}!</h1>

A minha duvida agora é: todo objeto q estiver na session eu somente tenho acesso caso passe-o no construtor? Ele nao fica ‘global’ na session para os Controllers e pras Views?

Adriano_Almeida

jurado:

A minha duvida agora é: todo objeto q estiver na session eu somente tenho acesso caso passe-o no construtor? Ele nao fica ‘global’ na session para os Controllers e pras Views?

A questão é que para vc usar esse objeto dentro da da sua lógica (o controller), vc vai precisar recebe-lo de alguma forma. E a melhor forma pra isso é pelo construtor, pq facilita muito na hora de escrever testes. E esse é um dos motivos para que no VRaptor é seja forma (tendo que receber no construtor).

Sobre a disponibilização para a view, você pode ter vários components que sejam session scoped, porém, não necessariamente todos eles devem ser expostos para a view, por isso, com o result.include você só manda pra view quem vc realmente precisa na lá.

Claro?
Qualquer outra dúvida posta aí.

[]'s

Lucas_Cavalcanti

Um truque pra quando você quer que seu componente session scoped seja acessado pelas views também,
você pode fazer:

@Component
@SessionScoped
public class UsuarioWrapper {
     public UsuarioWrapper(HttpSession session) {
         this.session = session;
     }
     public void setUsuario(Usuario usuario) {
            session.setAttribute("usuarioAutenticado", usuario);
     }

    public Usuario getUsuario() {
          return session.getAttribute("usuarioAutenticado");
     }

}

e no jsp:

${usuarioAutenticado.nome} - ${usuarioAutenticado.login}
jurado

Obrigado pelas respostas, pessoal. Muito uteis!!!

Em tempo: Bem bacana a iniciativa do VRaptor. Tou me divertindo pacas :slight_smile:

Uma outra questão sobre quando um objeto não é session scoped:

Eu preciso, exibir na view uma lista de outros objetos. Criei entao no controller:

public Collection<Grupo> listaGrupos() {
		System.out.println("Listando grupos...");
		return this.daoFactory.getGrupoDao().listaTudo();
	}

Porém, ao tentar acessá-lo na view assim:

<c:forEach var="grupo" items="${grupoList}">
		<option value="${grupo.idGrupo}">${grupo.codigo}</option>
	</c:forEach>

ele nao passa pela lista. Ela vem vazia. Somente funcionou após eu EXPLICITAMENTE incluir a lista resultado da chamada para o método no result. Ficou assim:

Controller:

public void adicionar() {
		result.include("listaGrupos", listaGrupos());
	}

e na view:

<c:forEach var="grupo" items="${listaGrupos}">
		<option value="${grupo.idGrupo}">${grupo.codigo}</option>
	</c:forEach>

Errei algo na primeira forma??? Nao ter q passar explicitamente para o result me parece mais elegante, porém, seguindo a documentacao que diz que qdo um método retorna uma collection de um determinado objeto ela seria acessada por objetoList nao funcionou neste caso…

Paulo_Silveira

oi jurado!

que versao de beta voce esta usando?

abracos!

jurado

Atualmente a ultima, Beta5.

Lucas_Cavalcanti

jurado, tenta voltar pro retorno do método…

aqui aconteceu essa mesma coisa, mas voltou a funcionar, estranhamente… ve se resolve pra vc tb…

[]'s

jurado

Nada feito… Aqui só funciona se eu insiro explicitamente no result… :frowning:

Lucas_Cavalcanti

ok… to com problemas pra simular esse bug… mas fica tranquilo que isso vai funcionar no vraptor sem problemas…
usa via result por enquanto =(

Lucas_Cavalcanti

a variável no jsp tá com o nome certinho?

tenta usar o result e dar o mesmo nome que o retorno do método daria, sem retornar no método:

Collection => clientList => result.include(“clientList”, …);

acabei de baixar o blank-project do site, criar uma lógica de listagem nele e rodar, e funcionou numa boa =(

jurado

Fiz o teste. Incluindo no result o nome que deveria ser incluido automaticamente funcionou. Se eu nao alterar, vem vazio… :frowning:

Lucas_Cavalcanti

faz o seguinte teste pra mim, por favor:

cria uma classe:

public class Abc {
}

cria uma lógica, em qualquer controller:

@Path("/teste")

public Collection teste() {

return Arrays.asList(new Abc(), new Abc());

}

cria o teste.jsp na pasta certa:

${abcList}

acesse a url /teste e veja se aparece uma lista de abc…

Fiz esse teste a partir do blank-project, e funcionou… faça aí também por favor, só pra ver se pode
ser alguma coisa que está diferente no seu projeto…

[]'s

jurado

Na verdade, o problema é um pouquinho diferente. Já vou pedindo desculpas se for algum erro de interpretação meu (provavelmente é!):

Eu preciso listar 3 collection para ser capaz de popular 3 selects em um formulario de inclusao/edicao de uma entidade.

Eu criei 3 métodos públicos no @Resource que devolvem estes collections:

public Collection<Grupo> listaGrupos() {
		return this.daoFactory.getGrupoDao().listaTudo();
	}

	public Collection<Rota> listaRotas() {
		return this.daoFactory.getRotaDao().listaTudo();
	}

	public Collection<Servico> listaServicos() {
		return this.daoFactory.getServicoDao().listaTudo();
	}

Meu formulário para edição de configuracao de campanha é entao renderizado pelo método seguinte:

public void formulario(String action,
			ConfiguracaoCampanha configuracaoCampanha) {
// minhas collections
		result.include("grupoList", listaGrupos());
		result.include("rotaList", listaRotas());
		result.include("servicoList", listaServicos());
// Outras coisas q meu form precisa para ser renderizado
		result.include("formAction", action);
		result.include("configuracaoCampanha", configuracaoCampanha);
	}

Só que para ele ser gerado, ele precisa dos três collections. Se eu nao enviá-los manipulando o result, eles vem vazios…

Este é meu jsp:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<head>
<link rel="stylesheet" type="text/css" href="shared/css/style.css" />
</head>
<h1>Grupo</h1>
<form action="edit" method="post"><input type="hidden"
	name="configuracaoCampanha.idConfiguracaoCampanha"
	value="${configuracaoCampanha.idConfiguracaoCampanha}" /> Grupo:<select
	name="configuracaoCampanha.grupo.idGrupo">
<!-- aqui eu faco a mencao a uma das Collections -->
	<c:forEach var="grupo" items="${grupoList}">
		<option value="${grupo.idGrupo}"
			<c:if test="${grupo.idGrupo == configuracaoCampanha.grupo.idGrupo}">selected="true"</c:if>>
		${grupo.codigo}</option>
	</c:forEach>
</select><br>

Rota:<select name="configuracaoCampanha.rota.idRota">
<!-- aqui eu faco a mencao a uma das Collections -->
	<c:forEach var="rota" items="${rotaList}">
		<option value="${rota.idRota}"
			<c:if test="${rota.idRota == configuracaoCampanha.rota.idRota}">selected="true"</c:if>>
		${rota.codigo}</option>
	</c:forEach>
</select><br>

Servico:<select name="configuracaoCampanha.servico.idServico">
<!-- aqui eu faco a mencao a uma das Collections -->
	<c:forEach var="servico" items="${servicoList}">
		<option value="${servico.idServico}"
			<c:if test="${servico.idServico == configuracaoCampanha.servico.idServico}">selected="true"</c:if>>
		${servico.nome}</option>
	</c:forEach>
</select><br>

Limite Tentativa:<input name="configuracaoCampanha.limiteTentativa"
	value="${configuracaoCampanha.limiteTentativa}" /><br>
FatorK:<input name="configuracaoCampanha.fatorK"
	value="${configuracaoCampanha.fatorK}" /> <input type="submit" /></form>

A minha questão é: Pelo fato de que as collections nao fazem parte do escopo do formulario (fazem parte do escopo do controller, isto sem dúvida), elas devem mesmo assim serem enviadas pelo result???

Lucas, seu teste funcionou perfeitamente. Visualizei os dois itens. Porem, não é a mesma situação pois a Collection está sendo devolvida pelo método q ‘renderiza’ o JSP, portanto faz parte do escopo da requisição. Tou viajando muito?

Lucas_Cavalcanti

Houve um pequeno erro de interpretação sim…

o que é exportado como variável pros jsps é o retorno da sua lógica, no seu caso o retorno
do método formulário seria usado…

por exemplo, para o método listaRotas, você vai ter uma rotaList só se você acessar a url
/nomedocontroller/listaRotas

como você quer exportar mais de uma lista, você tem que fazer isso explicitamente no result mesmo…

a idéia é a seguinte: se sua lógica exporta só uma variável pra jsp, você pode usar o retorno do método,
se exportar mais de uma variável, você precisa usar o result.include mesmo…

desculpa a confusão, e continue mandando dúvidas =)

[]'s

jurado

Muito obrigado!!!

Desculpe minha confusão! Acabei dando um trabalho danado!

Abraços

D

Uma dúvida, quando o retorno é exportado para a view, como ele pode ser acessado? É o próprio nome da classe?

T+

jurado

Exato, com a primeira letra minúscula. Se o retorno for uma collection, acesse via nomeDaClasseList.

Caso você queira acessar por algum outro nome, pode fazer manipulando o result.

Criado 16 de setembro de 2009
Ultima resposta 17 de set. de 2009
Respostas 17
Participantes 5