Retornar vários objetos por um método [Resolvido]

http://vraptor.caelum.com.br/documentacao/downloading/

na apostila tb fala isso, citando o InputStream, com mais detalhes…

[quote=Lucas Cavalcanti]http://vraptor.caelum.com.br/documentacao/downloading/

na apostila tb fala isso, citando o InputStream, com mais detalhes…
[/quote]

No link do site tem apenas File e FileDownload :smiley:

Ps: nunca ví um PDF tão bonito como os da Caelum. Simplesmente fantástico.

A dica do Lucas que eu não entendi. =/
Não posso pegar as fotos do Imovel pela id foto, só posso pegar pela id de imovel, por isso coloquei {imovel.idImovel}, se eu colocar {idImovel} não aparece nada na JSP.
Garcia, tentei com a classe Download (que eu não sabia que existia) e não deu certo, eu vi que vc manda as coordenadas por parâmetro, faz a busca e depois retorna os dados, estou seguindo a mesma lógica, mando o id do imóvel por parâmetro, itero essa listagem criando um FileInputStream e retorno esses files:

@Get
	@Path("/imagem/{idImovel}/") // idImovel nem aparece na JSP
	public Download imagem(Long idImovel) throws IOException {
		FileInputStream destino = null; // inicializo a variavel destino
		List<Foto> fotos = fotoDAO.getGaleria(idImovel); // Pego todas as fotos do DAO e aarmazeno na variavel "fotos". 
		List<FileInputStream> destinos = new LinkedList<FileInputStream>(); // crio uma variavel para armazenar a List de objetos
		for (Foto foto : fotos) {
			try {
				destino = new FileInputStream(new File("/home/bruno/fotos", foto.getUrlFoto())); // crio um file "destino"
				destinos.add(destino); // adiciono os "files" na lista
			} catch (FileNotFoundException e) {
				//result.notFound(); Aqui o Eclipse manda fazer Cast, ele coloca um (Object) antes de destinos e em seguida manda remover o Cast, o Result já está injetado no construtor.
				return null;
			}

		}
		return (Download) destinos; // retorno os objetos na lista, o Eclipse mandou fazer o cast para Download.	
	}	

Resultado disso na JSP:

http://localhost:8080/imobiliaria/imagem//

Você quer devolver uma ou muitas fotos? O componente de Download é para apenas UM arquivo.

O que o Lucas quer dizer é se você tem muitas fotos para um imóvel, você precisa passar é o ID da foto, e não do imóvel. Olhe no meu post que eu comentei sobre você fazer esse loop nas fotos e retornaer sempre a ultima foto.

Quero retornar várias fotos de um imóvel para mostrar na JSP, mas se eu envio apenas a id do imóvel como parâmetro, como iria buscar as fotos do imóvel pela id da Foto? Tenho duas tabelas, uma imóvel e outra Foto, é na tabela Foto que armazeno a id do imóvel como FK, estou usando a FK para pegar todas as fotos na classe FotoDAO.

@SuppressWarnings("unchecked")
	public List<Foto> getGaleria(Long idImovel) {		
	    return session.createQuery("from Foto f where f.imovel.id = :id")
		   .setParameter("id", idImovel)
		   .list();
}

Guevara, suas dúvidas vão além do Vraptor, na verdade isso é uma dúvida simples de HTML. Você NUNCA vai conseguir imprimir uma lista de imagens da forma que você quer fazer, em nenhuma linguagem, seja Java ou Ruby (isso é uma limitação do HTML mesmo).

Não existe como você mandar imprimir o stream direto no HTML da página. Você precisa criar uma imagem com a tag e no campo SRC (source) apontar para uma action do vraptor que irá montar a foto retornando para o browser um array de bytes com o cabeçalho image/(png ou gif ou jpg).

Como minhas aplicações todas usam cluster eu gravo todas as imagens no banco de dados. Então o que eu faço é quando monto a tela que tem as fotos eu retorno para a tela a lista de ids de fotos, entendeu? De posse desses IDs eu chamo as imagens via , onde 15 é o ID da foto. Simples até aqui.

Depois eu faço um método no vraptor que a partir do ID da foto ele retorne a foto em sí, conforme o exemplo que eu te passei há alguns posts atrás.

Não sei se fui bem claro. Mas o rumo é esse.

vc tem o id do imóvel, certo?

com o id do imóvel vc consegue pegar várias fotos, certo?

cada foto dessa tem um id, certo?

vc consegue buscar uma foto pelo id e retornar o inputStream dela, certo? (o código que eu mandei)

basta no seu jsp, vc receber a lista de fotos do imóvel (result.include(“fotos”, fotosDoImovel)), e fazer um foreach nessas fotos, usando pra mostrar cada foto (dentro do c:forEach…)

mas vc vai precisar da lógica que eu te mandei

Isso, pego assim:

@SuppressWarnings("unchecked")
	public List<Foto> getGaleria(Long idImovel) {		
	    return session.createQuery("from Foto f where f.imovel.id = :id")
		   .setParameter("id", idImovel)
		   .list();
}

Isso, mas só poderia pegar a foto por um id foto se eu mandasse por parâmetro um id foto, só que a unica id que é usada é a do imóvel, fiz aqui no componente Imagens:

public InputStream getPasta(Long idImovel) { //mandando id do imovel para pegar as fotos no metodo getGaleria()
FotoDAO fotoDAO = new FotoDAO(); // O método não funciona injetando o DAO no construtor, por isso instanciei aqui.
		List<Foto> fotos = fotoDAO.getGaleria(idImovel);
		for (Foto foto : fotos) {
		try {
			return new FileInputStream(new File("/home/bruno/fotos", foto.getUrlFoto()));
		} catch (FileNotFoundException e) {
			return null;
		}
		}
		return null;
	}

Fiz aqui:

public void adiciona(Long idImovel) {
		 result.include("imovel", imovelDAO.carrega(idImovel));	
		  result.include("fotos", fotoDAO.getGaleria(idImovel));	// mandando url das fotos	 
	 }
<c:forEach var="foto" items="${fotos}">
    <ul>
        <li>
           <a href="<c:url value="/imagem/${imovel.idImovel }/${foto.urlFoto}"/>"/>
             
                      
            <img src="<c:url value="/imagem/${imovel.idImovel }/${foto.urlFoto }"/>" />                     	                        	 
            
            </a>
        </li>
   </ul>
</c:forEach>

Resultado:

=/

faça no jsp:

    <ul>
   <c:forEach var="foto" items="${fotos}">

        <li>
           <img src="<c:url value="/imagem/${foto.id }"/>" />
        </li>

    </c:forEach>
   </ul>

no controller (outro método):

@Path("/imagem/{idFoto}")
public InputStream mostraFoto(Long idFoto) throws FileNotFoundException {
     FotoDAO fotoDAO = new FotoDAO(); // pra injetar no construtor é só anotar o dao com @Component
     Foto foto = fotoDAO.carrega(idFoto); 
     return new FileInputStream(new File("/home/bruno/fotos", foto.getUrlFoto()));
}

entendeu agora?

Deu certo!!! \o/

Coloquei o LightBox junto. =)
A única coisa que precisei fazer foi um método “carrega” na DAO, isso eu não tinha.
Ainda não consegui entender como ele está instânciando um FileInputStream de um determinado imóvel sem ter a id do imóvel sendo passada por parâmetro. O.o
Será pelo motivo de já ter um objeto imóvel carregado na página?
Obrigado pelo ajuda Lucas e Garcia, principalmente pela paciência, sem a ajuda de vcs não teria conseguido.
Abraço!

vc não tá carregando o FileInputStream do Imóvel, e sim da Foto do imóvel… e ele tá carregando pq vc tah passando o id da foto

dá uma lida na apostila do FJ-11 da caelum pra saber direito o que eh um InputStream…

Eu compro o mercedão!!! :twisted:

Eu sei que é InputStream da Foto, o que eu não entendi é como ele sabe que aquelas fotos são do imóvel correto já que não é passada a id do imóvel.
Como essa parte de InputStream eu sou leigo ainda, vou dar uma lida na apostila pra entender como essa mágica aconteceu.

Garcia, esses ônibus rodam até hj no meu bairro, fica em Buenos Aires - Argentina. :lol:
Os motoristas cuidam desses ônibus como se fossem seus filhos.

ele sabe que as fotos são do imóvel, pq vc iterou pelas fotos do imóvel, usando os ids delas…