Pego a lista de url das fotos e crio vários Files, mas tá dando zica no “return”. Como posso retornar essas fotos para que sejam mostradas na JSP?
Abraço!
Guevara, sugiro você dar uma lida muito boa no Java Collections, pois notei que você não conhece nada sobre elas, e é muito importante para o desenvolvimento você ter uma noção mínima sobre elas.
Nesse caso você precisará retornar no seu método uma lista de fotos, algo como:
public List<File> mostra(Long idImovel) {
List<File> destinos= new LinkedList<File>();
List<String> fotos = fotoDAO.getFotos(idImovel);
for(String foto: fotos) {
File destino = new File(pastaImagens, foto);
destinos.add(destino);
}
return destinos; //este return
}
vc não vai conseguir mostrar as fotos usando o new File(…) pois ele retorna o caminho da foto no servidor, e isso não adianta pra mostrar na página…
se vc salvou as imagens dentro de uma pasta da sua aplicação (usou context.getRealPath, ou coisas do tipo), vc pode retornar esse caminho, e com ele vc consegue mostrar a imagem…
se vc salvou em uma pasta fora da aplicação, ou dentro da pasta WEB-INF vc vai ter que criar uma lógica pra mostrar cada imagens…
Guevara
Estou fazendo um teste aqui pra mostrar o nome e a url salva no banco, mas não está mostrando nada:
tudo bem que esteja fazendo a consulta, mas está retornando resultados na consulta?
Guevara
Pois é Lucas, colocando o breakpoint no result.include e no return do método getGaleria() na DAO só me dá este resultado:
Navegando pela árvore não consigo achar nada do objeto Foto. =/
Guevara
Alterei a consulta:
@SuppressWarnings("unchecked")publicList<Foto>getFoto(LongidImovel){returnsession.createQuery("select f.urlFoto, f.nome from Foto f where f.imovel.id = :id").setParameter("id",idImovel).list();}
Eu reparei que ele está querendo converter, mas isso é impossível, não têm nada pra converter, a coluna “nome” é varchar no banco.
Mesmo problema rodando esta consulta:
@SuppressWarnings("unchecked")publicList<Foto>getGaleria(LongidImovel){returnsession.createSQLQuery("select nome, url_foto from Foto where imovel_id_imovel = :id").setParameter("id",idImovel).list();
Você itera em uma variável reassociando com ela mesma? Outra coisa, o retorno do Vraptor não seria fotoList quando o retorno do método é List?
Guevara
Pois é Garcia, eu tô fazendo por analogia, se funciona em outra página têm que funcionar em outra, tenho outro método para Imóvel que funciona, e agora não. Exemplo:
Não consigo entender essas frescuras, que não sei se é por causa da consulta ou se é por causa da jstl, no primeiro caso a consulta é na tabela imóvel, o segundo caso é na tabela filha Foto. Fazer consultas nessas tabelas está sendo um parto com Criteria e Query.
Guevara
@SuppressWarnings("unchecked")publicList<Foto>getGaleria(LongidImovel){returnsession.createSQLQuery("select nome, url_foto from Foto where imovel_id_imovel = :id").setParameter("id",idImovel).list();
Pois é, ontem eu estava lendo uns tópicos antigos e notei que você está tendo muitos problemas que eu ainda não tinha visto. Pense positivo: você é um “bugs-finder”, hahahahaha.
Brincadeiras a parte, embora eu não use os objetos como retorno dos métodos do controller posso jurar que quando você usa assim o vraptor retorna como nome-do-objeto + List (no seu caso seria fotoList). Talvez na sua outra tela você retorne via results.include, não?
E até por questão de legibilidade, quando você tem mais de uma foto é normal usar ou plural ou um sufixo List, assim você se organiza melhor e evita pequenos erros bobos.
G
garcia-jj
Guevara, me permita te dar um puxão de orelha :oops: ? Vocẽ precisa ler um pouco as APIs antes de usá-la. Olhe bem seu exemplo:
No controller
E no JSP
Ou seja, você exporta as suas fotos como fotos, então você deve fazer algo como:
Ou seja, VAR é o nome que o objeto receberá a cada iteração, e fotos é sua coleção de objetos. Traduzindo em Java seria como isso aqui:
Guevara
Tô penando aqui pra resolver esses “bugs”. Eu vejo o pessoal do RubyOnRails e Python desenvolvendo coisas como essas sem problemas, enquanto no Java td é mais burocrático, embora o VRaptor dê a agilidade a própria linguagem não dá. Se tiver dois casos iguais, um vai dar certo e outro não, e nessa brincadeira o tempo vai embora e não se produz nada.
Nesse meu último post coloquei como vc sugeriu, e veja que não mostra nada na JSP, detalhe, nem erros aparecem no console, é ai que na minha opinião o desenvolvimento em Java fica no chinelo em comparação com as outras linguagens que citei.
Se existem dois casos iguais, os dois obrigatóriamente devem dar o mesmo resultado. Nos dois retorna a lista de objetos, nos dois a lista é enviada via result.include, e óbviamente vou pegar na JSP da mesma forma, mas não, um funciona e o outro não. =/
Guevara
Pois é Garcia, eu estava fazendo certo, e como não funciona fui tentando adivinhar o que ele quer, se eu colocar desse jeito olha o resultado:
Voltamos ao mesmo problema de alguns posts atrás, ele tenta converter o que é uma String/Varchar para Integer.
Vê se isso têm explicação… =/
G
garcia-jj
O problema é que muitas linguagens o programador pode ir na base do chutômetro, ou como eu digo, na base da tentativa e erro. No Java não é que tudo é mais complicado, só é necessário que o programador leia o mínimo que seja para aprender a usar a API. Boa parte dos erros que eu notei que você teve é por não conhecer a API. Então acho que é um pouco cedo para você dizer que Java é complicado, afinal você ainda não conhece Java o suficiente para ter uma produtividade.
Trabalho há ~13 anos com Java, e conheço muito pouco de RoR e Python, então não posso mesmo fazer uma comparação. Mas creio que, como eu te disse, quando você conhecer um pouco melhor a API vai ver como Java é bem simples.
Teus códigos me pareceram diferentes. Um deles usa o retorno no próprio método do controller, já o outro usa via results.include.
Altere esses seus forEachs para não dar conflito de variáveis conforme eu já escrevi acima e também verifique os retornos dos controllers, passe tudo via results.include. Além disso verifiquei se você está passando os tipos corretos e não há mais de uma variável com o mesmo nome.
Fora isso eu não sei mais com ajudar.
Lucas_Cavalcanti
isso:
<c:forEachvar="imovel"items="${imovel}">
não é certo…
items tem que ser uma lista, e o var é a variável que vc chama cada elemento da lista…
o código está funcionando por coincidência…
se vc deu um result.include(“fotos”, …), vc tem que acessar no jsp via ${fotos}, e colocar isso na parte items:
No exemplo o id é do imóvel que é a FK de foto e não a PK.
Tô dando ctrl+space pra descobrir qual seria o parâmetro pra isso mas não consegui descobrir.
Lucas_Cavalcanti
session.createQuery("from Foto f where f.idImovel = :id")
.setParameter("id", idImovel)
.uniqueResult();
Guevara
Obrigado Lucas. =)
Vou ver o que consigo aqui.
Guevara
Consegui pegar os endereços e jogar na JSP, mas aconteceu o que eu imaginava, tá pegando o caminho como se fosse dentro do contexto da aplicação, quando na verdade está fora:
Tá mostrando assim:
Na JSP não mostra a imagem, mas se eu pegar o endereço file:///home/bruno/fotos/42.xx.252(1).jpg que aparece num pequeno retângulo onde deveria aparecer a imagem e jogar no browser a imagem aparece. Essa tática de usar o endereço físico file:/// tb é furada?
Abraço!
Guevara
Na JSP não mostra a imagem mas o caminho mostra corretamente:
Mas não está instanciando o método InputStream, coloquei um breakpoint nos retornos de cada método mas passa batido.
Se o método funcionar acredito que a imagem apareça na JSP. =)
Lucas_Cavalcanti
não use file://
faça o controller exatamente do jeito que eu coloquei na minha última mensagem…
Guevara
Então Lucas, o método está retornando null, colocando no componente ou no controller:
quanto a não criar a pasta, vc deu uma olhada no sistema pra ver se ela existe mesmo? vc tem permissão pra criar essa pasta, a partir da sua app?
Guevara
Oi Lucas!
A pasta está liberada para incluir e deletar fotos, eu segui a sua lógica, mas o problema é que preciso passar a ID do imóvel para que sejam carregadas as fotos daquele imóvel, não dá pra colocar apenas uma String caminho, preciso da ID do imóvel, então fiz assim:
No componente:
Coloquei um breakpoint pra saber se o return tá mandando alguma coisa:
E no controller eu envio esse InputStream via result.include quando a página adiciona.jsp é chamada:
Agora o que eu não consegui achar é como mostrar isso na JSP.
Lucas_Cavalcanti
vc não vai conseguir mostrar o inputStream via variável… vc precisa criar uma lógica que retorna esse inputStream mesmo, e na jsp vc chama essa lógica dentro de uma tag img, por exemplo:
<imgsrc="/imagem/${imovel.id}"alt="imovel.nome"/>
e a lógica que responde por /imagem/{imovel.id} vai retornar o InputStream…
Guevara
Fiz uns testes aqui e constatei que só o result.include consegue trazer os dados das fotos, se eu colocar o método no Controller vêm td null.
e na listagem do imóvel vc vai criar as <img baseado no id de cada foto do imóvel
G
garcia-jj
Não entendo uma coisa... você faz um loop em várias fotos mas retorna apenas o stream da última? Analise o seu loop e veja que você retorna o stream apenas da última. Além disso você não deveria retornar um stream para o JSP, e sim retornar um FileDownloadStream no seu método.
Outra coisa, não esconda as exceptions, isso é muito perigoso. Se algum erro acontecer você nunca saberá. Apenas faça um catch se você quer tratar a exception.
Segue um exemplo meu usando os componentes de download do vraptor. No meu caso esse código é de uma ferramenta de geoprocessamento que a partir de uma coordenada geografica traz o mapa do local.
na apostila tb fala isso, citando o InputStream, com mais detalhes…
No link do site tem apenas File e FileDownload
Ps: nunca ví um PDF tão bonito como os da Caelum. Simplesmente fantástico.
Guevara
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:
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.
Guevara
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")publicList<Foto>getGaleria(LongidImovel){returnsession.createQuery("from Foto f where f.imovel.id = :id").setParameter("id",idImovel).list();}
G
garcia-jj
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.
Lucas_Cavalcanti
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
Guevara
Isso, pego assim:
@SuppressWarnings("unchecked")publicList<Foto>getGaleria(LongidImovel){returnsession.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:
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!
Lucas_Cavalcanti
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…
G
garcia-jj
Eu compro o mercedão!!! :twisted:
Guevara
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.
Lucas_Cavalcanti
ele sabe que as fotos são do imóvel, pq vc iterou pelas fotos do imóvel, usando os ids delas…