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

Olá!
Estou tentando retornar várias fotos por um método do componente Imagens:

public File mostra(Long idImovel) {
		List<String> fotos = fotoDAO.getFotos(idImovel);
		for(String foto: fotos) {
		File destino = new File(pastaImagens, foto);
		}
		return destino; //este return 
	}

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 retorna uma List (arrayList) do objeto mesmo…

ex1

public List mostra(Long idImovel) {  
        List<String> fotos = fotoDAO.getFotos(idImovel);  
        List files = new ArrayList( fotos.size() );
        for(String foto: fotos) {  
           files.add(  new File(pastaImagens, foto) );  
        }  
        return files; //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…

Estou fazendo um teste aqui pra mostrar o nome e a url salva no banco, mas não está mostrando nada:

<fieldset>
<legend>Galeria</legend>        
<c:forEach var="foto" items="${foto}"> 
<p>${foto.nome }</p>
<p>${foto.urlFoto }</p>
</c:forEach> 
</fieldset>

Estou enviando o nome e url pelo Controller assim:

public void adiciona(Long idImovel) {
		 result.include("imovel", imovelDAO.carregaId(idImovel));
		 result.include("foto", fotoDAO.getGaleria(idImovel));
	 }	 	

E na classe FotoDAO está assim:

@SuppressWarnings("unchecked")
	public List<Foto> getGaleria(Long idImovel) {
		return session.createCriteria(Foto.class, "f")
		.setProjection(Projections.projectionList()
				.add( Projections.property("f.nome").as("nome") )
				.add( Projections.property("f.urlFoto").as("urlFoto") )
				).setResultTransformer(new AliasToBeanResultTransformer(Foto.class))
				.add(Restrictions.idEq(idImovel)).list();
	}

Tinha que printar na tela esses dados não? O.o
Abraço!!!

a busca tá retornando algum resultado? não tá imprimindo nada na tela?

Oi Lucas!
Está fazendo a consulta mas não mostra nada na JSP:

01:07:21,458 DEBUG [OgnlParametersProvider] Applying idImovel with [42]
01:07:21,471 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for FotoController.adiciona(Long) as [idImovel]
01:07:21,471 DEBUG [ParametersInstantiatorInterceptor] Parameter values for [DefaultResourceMethod: FotoController.adicionaFotoController.adiciona(Long)] are [42]
01:07:21,498 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExecuteMethodInterceptor
01:07:21,498 DEBUG [ExecuteMethodInterceptor] Invoking FotoController.adiciona(Long)
Hibernate: 
    select
        this_.id_imovel as y0_ 
    from
        Imovel this_
Hibernate: 
    select
        this_.nome as y0_,
        this_.url_foto as y1_ 
    from
        Foto this_ 
    where
        this_.id_foto = ?
01:07:21,515 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor OutjectResult
01:07:21,521 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ForwardToDefaultViewInterceptor
01:07:21,521 DEBUG [ForwardToDefaultViewInterceptor] forwarding to the dafault page for this logic
01:07:21,530 DEBUG [DefaultPageResult   ] forwarding to /WEB-INF/jsp/foto/adiciona.jsp
01:07:21,531 DEBUG [DefaultStaticContentHandler] Deferring request to container: /imobiliaria/WEB-INF/jsp/foto/adiciona.jsp 
01:07:23,592 DEBUG [VRaptor             ] VRaptor ended the request

tudo bem que esteja fazendo a consulta, mas está retornando resultados na consulta?

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. =/

Alterei a consulta:

@SuppressWarnings("unchecked")
	public List<Foto> getFoto(Long idImovel) {
		return session.createQuery("select f.urlFoto, f.nome from Foto f where f.imovel.id = :id")  
        .setParameter("id", idImovel).list();
	}
Hibernate: 
    select
        this_.id_imovel as y0_ 
    from
        Imovel this_
Hibernate: 
    select
        foto0_.url_foto as col_0_0_,
        foto0_.nome as col_1_0_ 
    from
        Foto foto0_ 
    where
        foto0_.imovel_id_imovel=?

Acho que agora está certo ----> foto0_.imovel_id_imovel=?
Tá dando pau na JSP:

[code]
Galeria
<c:forEach var=“foto” items="${foto}">

  • ${foto.nome }
  • ${foto.urlFoto }
  • [/code] O erro é: [code] root cause java.lang.NumberFormatException: For input string: "nome" java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) java.lang.Integer.parseInt(Integer.java:449) java.lang.Integer.parseInt(Integer.java:499) javax.el.ArrayELResolver.coerce(ArrayELResolver.java:161) javax.el.ArrayELResolver.getValue(ArrayELResolver.java:45) javax.el.CompositeELResolver.getValue(CompositeELResolver.java:54) org.apache.el.parser.AstValue.getValue(AstValue.java:123) org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:935) org.apache.jsp.WEB_002dINF.jsp.foto.adiciona_jsp._jspx_meth_c_005fforEach_005f1(adiciona_jsp.java:313) org.apache.jsp.WEB_002dINF.jsp.foto.adiciona_jsp._jspService(adiciona_jsp.java:147)

    [/code]
    No Controller:

    result.include("foto", fotoDAO.getFoto(idImovel));

    Note isso aqui:

    Seu erro é no JSP. Como está o seu forEach nesse JSP? Conforme a mensagem do erro note que ele tenta transformar a String nome em Integer.

    Oi Garcia!
    Na jsp está assim:

    <fieldset>
    	 <legend>Galeria</legend>     
    	 	<table>
        		<tr>    
        			<td>Nome</td>
        			<th>url</th>    
         		</tr>  
    		<c:forEach var="foto" items="${foto}"> 
     			<tr>  
    				<td>${foto.nome }</td>
    				<td>${foto.urlFoto }</td>
    			</tr>
    		</c:forEach> 
    		</table>
    </fieldset>

    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")
    	public List<Foto> getGaleria(Long idImovel) {
    		return session.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<Foto>?

    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?

    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:

    <c:forEach var="imovel" items="${imovel}">
        <tr>    	 
            <td>${imovel.codImovel }</td>
            <td>${imovel.titulo }</td>        
            <td>${imovel.bairro }</td>
    		<td>${imovel.valor }</td>  
        </tr>
    </c:forEach>

    Isto funciona.

    Mas isto não funciona:

    <fieldset>
      <table>
        	<tr>    
        		<td>Nome</td>
        		<td>url</td>
        	</tr>      
    		<tr> 
    	<c:forEach var="foto" items="${foto}">  
    		<tr>
        		<td>${foto.nome}</td>  
        		<td>${foto.urlFoto}</td>  
    	</c:forEach> 
    	   </tr>
     </table>
    </fieldset>

    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.

    @SuppressWarnings("unchecked")
    	public List<Foto> getGaleria(Long idImovel) {
    		
    		return session.createSQLQuery("select nome, url_foto from Foto where imovel_id_imovel = :id")
    		.setParameter("id", idImovel).list();
    Hibernate: 
        select
            nome,
            url_foto 
        from
            Foto 
        where
            imovel_id_imovel = ?
    public void adiciona(Long idImovel) {
    		 result.include("imovel", imovelDAO.carregaId(idImovel));
    		 result.include("fotos", fotoDAO.getGaleria(idImovel));
    	 }	
    <c:forEach var="fotos" items="${fotoList}">  
    		<tr>
        		<td>${fotos.nome}</td>  
        		<td>${fotos.urlFoto}</td>  
    	</c:forEach> 

    Resultado:

    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.

    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:

    :smiley: 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. =/

    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:

    result.include("fotos", fotoDAO.getGaleria(idImovel));
    <c:forEach var="foto" items="${fotos}">  
    		<tr>
        		<td>${foto.nome}</td>  
        		<td>${foto.urlFoto}</td>  
    	</c:forEach> 
    java.lang.NumberFormatException: For input string: "nome"
    	java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    	java.lang.Integer.parseInt(Integer.java:449)
    	java.lang.Integer.parseInt(Integer.java:499)
    

    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… =/

    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.