isso:
<c:forEach var="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:
<c:forEach var="foto" items="${fotos}">
<tr>
<td>${foto.nome}</td>
<td>${foto.urlFoto}</td>
</tr>
</c:forEach>
Agradeço aos dois pela ajuda. 
Sabem me dizer como carrego um objeto pela FK neste exemplo?
public Foto carrega(Long idImovel) {
return (Foto) this.session.load(Foto.class, idImovel);
}
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.
session.createQuery("from Foto f where f.idImovel = :id")
.setParameter("id", idImovel)
.uniqueResult();
Obrigado Lucas. =)
Vou ver o que consigo aqui.
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:
http://localhost:8080/imobiliaria/home/bruno/fotos/42.xx.252(1).jpg
O código na JSP que usei foi este:
<img src="${pageContext.request.contextPath}/home/bruno/fotos/${foto.urlFoto }"/>
Alguém conhece alguma EL ou taglib que consiga acessar o contexto externo?
Tõ pesquisando por “external context path”.
Abraço!
<img src="<c:url value="/home/bruno/fotos/${foto.urlFoto }"/>" />
Oi Lucas!
Não deu certo, ele continua pegando como se fosse dentro do contexto da aplicação:
http://localhost:8080/imobiliaria/home/bruno/fotos/42.xx.252(1).jpg
Será que rola criar um contexto apontando para a pasta dentro de algum xml? Algo como:
<Context path="/home/bruno/fotos" docBase="/home/bruno/fotos"
//alguma coisa aqui que não faço idéia.
</Context>
vc quer que vá pra uma pasta física dentro do seu computador?
você não deveria fazer isso nunca na vida… imagina se eu chamar: http://localhost:8080/imobiliaria/etc/passwd
eu veria seus passwords!
se vc quiser fazer essa correspondência, crie uma lógica do tipo:
@Path("/imagens/{caminho*}")
public InputStream imagem(String caminho) {
try {
return new FileInputStream("/home/bruno/fotos/" + caminho);
} catch (FileNotFoundException e) {
result.notFound();
return null;
}
}
daí vc só acessa http://localhost:8080/imobiliaria/imagens/42.xx.252(1).jpg e ele mapeia para a pasta física
(claro que vc vai mudar o código que eu passei, pra ele ficar mais configurável e tal, isso eh soh um exemplo)
Beleza Lucas!
Vou tentar aqui com essa lógica.
Eu tentei aqui com:
<img src="<c:url value="file:///home/bruno/fotos/${foto.urlFoto }"/>" />
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!
Na JSP não mostra a imagem mas o caminho mostra corretamente:
http://localhost:8080/imobiliaria/imagem/42.xx.252(1).jpg
No Controller:
@Get
@Path("/imagem/")
public InputStream getPasta() {
return imagens.getPasta();
}
public void adiciona(Long idImovel) {
result.include("imovel", imovelDAO.carrega(idImovel));
result.include("fotos", fotoDAO.getGaleria(idImovel)); // aqui eu mando o nome completo da foto
}
No Componente Imagens:
public InputStream getPasta() {
try {
return new FileInputStream(pastaImagens);
} catch (java.io.FileNotFoundException e) {
return null;
}
}
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. =)
não use file://
faça o controller exatamente do jeito que eu coloquei na minha última mensagem…
Então Lucas, o método está retornando null, colocando no componente ou no controller:
public InputStream getPasta() {
try {
return new FileInputStream(pastaImagens);
} catch (FileNotFoundException e) {
return null;
}
}
Retorna null no debug.
Eu tô colocando no componente pq lá já tenho o caminho:
public Imagens() {
String pastaImagens = "/home/bruno/fotos";
this.pastaImagens = new File(pastaImagens);
File destino = new File(pastaImagens);
destino.mkdir();
}
No Controller:
@Get
@Path("/imagem/")
public InputStream imagem() {
return imagens.getPasta();
}
Mesmo colocando o código todo no controller retorna null, não está criando a pasta.
a idéia da lógica do controller NÃO é retornar a pasta…
é retornar a imagem direto! vc não pode retornar uma pasta como inputStream!!! nem faz sentido…
o que vc tem que fazer no controller é o que eu falei pra vc fazer naquela mensagem:
@Get
@Path("/imagem/{caminho*}")
public InputStream imagem(String caminho) {
try {
return new FileInputStream(new File(caminho, imagens.getPasta()));
} catch (FileNotFoundException e) {
result.notFound();
return null;
}
}
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?
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:
public InputStream getPasta(Long idImovel) {
FileInputStream destino = null;
FotoDAO fotoDAO = new FotoDAO();
List<Foto> fotos = fotoDAO.getGaleria(idImovel);
for (Foto foto : fotos) {
try {
destino = new FileInputStream(new File(pastaImagens, foto.getUrlFoto()));
} catch (java.io.FileNotFoundException e) {
e.printStackTrace();
}
}
return destino;
}
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:
public void adiciona(Long idImovel) {
result.include("imovel", imovelDAO.carrega(idImovel));
result.include("fotos", imagens.getPasta(idImovel));
}
Agora o que eu não consegui achar é como mostrar isso na JSP.
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:
<img src="/imagem/${imovel.id}" alt="imovel.nome"/>
e a lógica que responde por /imagem/{imovel.id} vai retornar o InputStream…
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.
@Path("/imagem/{imovel.idImovel}/")
public InputStream imagem(Long idImovel) {
FileInputStream destino = null;
FotoDAO fotoDAO = new FotoDAO();
List<Foto> fotos = fotoDAO.getGaleria(idImovel);
for (Foto foto : fotos) {
try {
destino = new FileInputStream(new File("/home/bruno/fotos", foto.getUrlFoto()));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
return destino;
}

se vc tem um parâmetro Long idImovel, o parâmetro no @Path tem que se chamar idImovel
@Path("/imagem/{idImovel}/")
e se vc tem várias imagens por imóvel, vc precisa pegar pelo id da Foto, não pelo id do imóvel…
@Path("/imagem/{idFoto}")
public InputStream imagem(Long idFoto) {
FotoDAO fotoDAO = new FotoDAO();// vc não deveria fazer isso aqui! receba no construtor!
Foto foto = fotoDAO.carrega(idFoto);
try {
return new FileInputStream(new File("/home/bruno/fotos", foto.getUrlFoto()));
} catch (FileNotFoundException e) {
result.notFound(); // receba esse result no construtor tb
return null;
}
}
e na listagem do imóvel vc vai criar as <img baseado no id de cada foto do imóvel
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.
[code] @Path("/l10n/map/{coordX}/{coordY}/")
public Download map(double coordX, double coordY)
throws IOException {
FilePNG png = gisRemote.find(coordX, coordY);
return new InputStreamDownload(file.getStream(), "image/png", file.getName());
}
[/code]
se vc retorna um InputStream o vraptor transforma em download automaticamente
Hmm, achei que era apenas <? implements Download> (nos docs não diz isso). Mas faz sentido já que o File também faz download.