File Upload PrimeFaces - Salvar imagem no contexto do projeto

22 respostas
L

Oi
Eu estou desenvolvendo um projeto web usando prime faces e estou com a seguinte dificuldade.
Eu quero fazer o upload de uma imagem e salvar ela em disco em uma pasta temporária para ser acessada pela minha página
por exemplo (http://localhost:8084/webApp/tmp/imagem.jpg)
Com o código que eu fiz até agora eu consegui salvar a imagem em disco passando um endereço no disco local mas quando eu salvo no contexto do projeto para ser acessada pela página não funciona.
Quando eu salvo
“D:\imagem.jpg” - Funciona
“/imagem.jpg” ou “./imagem.jpg” - Não Funciona

Ai vão os códigos

Página Web

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:prime="http://primefaces.prime.com.tr/ui"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title></title>
    </h:head>
    <h:body>
        <h:form>
            <prime:fileUpload fileUploadListener="#{indexBean.uploadLogo}" label="Selecionar" allowTypes="*.jpg; *.png; *.gif;" multiple="false" auto="true" description="Arquivo de Imagem" />
        </h:form>
    </h:body>
</html>

Função do Bean

...
public void uploadLogo(FileUploadEvent evt) {
        try {
            setLogo((DefaultUploadedFile) evt.getFile());
            imagemURL = "./tmp/" + evt.getFile().getFileName();
            FileOutputStream fos = new FileOutputStream(imagemURL);
            fos.write(evt.getFile().getContents());
            fos.flush();
            fos.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(IndexBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(IndexBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
...

Mensagem de Erro

SEVERE: null
java.io.FileNotFoundException: .\tmp\Tulips.jpg (O sistema não pode encontrar o caminho especificado)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:70)
        at kprojects.clickentregas.controle.bean.IndexBean.uploadLogo(IndexBean.java:37)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.el.parser.AstValue.invoke(AstValue.java:191)
        at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
        at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:98)
        at org.primefaces.component.fileupload.FileUpload.broadcast(FileUpload.java:238)
        at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:740)
        at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:943)
        at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
        at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:77)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:859)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:579)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1555)
        at java.lang.Thread.run(Thread.java:619)

22 Respostas

A

o erro na na hora do upload ou na hora de resgatar a imagem?

B

Veja este exemplo:

http://benignosales.wordpress.com/2010/11/05/jsf-2-0-primefaces-crud-com-foto-utilizando-pfileupload/

Em um dos comentários ensino como salvar o arquivo em uma pasta da aplicação.

+ou- assim:

byte[] foto = event.getFile().getContents(); String nomeArquivo = event.getFile().getFileName(); FacesContext facesContext = FacesContext.getCurrentInstance(); ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext(); String arquivo = scontext.getRealPath("/WEB-INF/upload/" + nomeArquivo); criaArquivo(foto, arquivo);

O arquivo ficará na pasta /WEB-INF/upload/ da sua aplicação.

Valeu!

L

blz, vou testar e depois eu posto se funcionou e como ficou meu código

L

Isso ai funcionou
mas o arquivo ficou oculto -.-’
sabe o que pode ter sido?

R

Olá.

E quando se utiliza o MAVEN2 ??

Estou dizendo isso porque ele cria pastas diferentes para códigos (src/java) e imagens (src/resources). Quando vc faz o deploy no TOMCAT a pasta RESOURCES foi para dentro de classes (WEB-INF/classes/). Confesso que eu pensei que ficasse fora da pasta classes (em WEB-INF)

Tem como mudar o local da pasta RESOURCES no WAR ?? Por exemplo, os resources ficar somente em WEB-INF e não em WEB-INF/classes.

Ricardo

D

benignoms:
Veja este exemplo:

http://benignosales.wordpress.com/2010/11/05/jsf-2-0-primefaces-crud-com-foto-utilizando-pfileupload/

Em um dos comentários ensino como salvar o arquivo em uma pasta da aplicação.

+ou- assim:

byte[] foto = event.getFile().getContents(); String nomeArquivo = event.getFile().getFileName(); FacesContext facesContext = FacesContext.getCurrentInstance(); ServletContext scontext = (ServletContext) facesContext.getExternalContext().getContext(); String arquivo = scontext.getRealPath("/WEB-INF/upload/" + nomeArquivo); criaArquivo(foto, arquivo);

O arquivo ficará na pasta /WEB-INF/upload/ da sua aplicação.

Valeu!

Rapaz, interessante, mas como eu faço pra pegar o caminho e o nome do arquivo e jogar em um imputText???

L

Não entendi bem se é isso que você quer mas…
Se você usar o primefaces da uma olhada no showcase
http://www.primefaces.org/showcase-labs/ui/fileUploadSimple.jsf

Com html puro acho que é

D

llucas:
Não entendi bem se é isso que você quer mas…
Se você usar o primefaces da uma olhada no showcase
http://www.primefaces.org/showcase-labs/ui/fileUploadSimple.jsf

Com html puro acho que é

Opa era isso mesmo, obrigado!

Eu tenho um tópico nesse link abaixo e ninguém até agora deu noticias, será que tu pode dar uma olhada pra mim fera? É coisa bem pequena. Ta tudo funcionando, o código ta prontinho so tem um pequeno detalhe.

D

llucas:
Não entendi bem se é isso que você quer mas…
Se você usar o primefaces da uma olhada no showcase
http://www.primefaces.org/showcase-labs/ui/fileUploadSimple.jsf

Com html puro acho que é

Na verdade esse que tu me passou é do 3.0, eu uso 2.2.1 e nele não tem as propriedades. Teria que ser uma manipulação mesmo.

L

Estou realizando upload de imagens dentro do contexto do projeto, mas a imagem não renderiza.

Ela somente renderiza depois que atualizo a pasta pelo netBeans.

Alguém sabe como resolver esse problema?

P

lexmaximo,

você conseguiu resolver esse seu problema?

F

Pessoal estou com um problema…

Estou salvando corretamente, visualizando as imagens salvas também…

o problema é que ao salvar dentro do contexto, como estou em um ambiente teste(na minha própria máquina) qualquer alteração que eu faça tenho que dar full publish no jboss pras alterações funcionarem. Quando faço isso, perco as imagens que eu salvei dentro do contexto do projeto…
Tem como sanar este problema!?

Está aqui um ótimo tutorial pra quem tiver problema com este tipo de upload dentro do contexto do projeto.

quanto ao mostrar as imagens apenas setei o mesmo caminho no qual salvei dentro do value do p:graphicImage

<p:ring value="#{imagemMb.listagem}" var="exame" styleClass="image-ring" easing="easeInOutBack">
	<p:graphicImage value="/resource/exames/#{exame.dsNome}" width="100%" height="100%"/>	
</p:ring>
E

Acredito que só fazendo backup das imagens e depois colocando elas de volta, mas é um trabalho bem chato e extremamente não recomendável.
Salve fora do contexto do projeto. Se nos testes está tendo problema, imagina em produção…

F

ErickRAR:
Acredito que só fazendo backup das imagens e depois colocando elas de volta, mas é um trabalho bem chato e extremamente não recomendável.
Salve fora do contexto do projeto. Se nos testes está tendo problema, imagina em produção…

Mas como vou jogar esse caminho dentro do p:graphicImage para mostra-la?

E

Salve fora do contexto ou em um servidor de imagens e guarde o caminho/link no banco de dados. quando for mostrar ,basta recuperar o caminho pelo banco de dados.

Se quiser um outro servidor, na Amazon para hospedar arquivos no S3 é ridiculamente barato e a API deles é bem fácil de utilizar.

F

ErickRAR:
Salve fora do contexto ou em um servidor de imagens e guarde o caminho/link no banco de dados. quando for mostrar ,basta recuperar o caminho pelo banco de dados.

Se quiser um outro servidor, na Amazon para hospedar arquivos no S3 é ridiculamente barato e a API deles é bem fácil de utilizar.

Mesmo sendo fora do contexto eu buscando esse caminho e jogando a variável o sistema reconhecerá o caminho corretamente?
Pensei em fazer dessa forma, mas não sabia se daria certo.

F

ErickRAR:
Salve fora do contexto ou em um servidor de imagens e guarde o caminho/link no banco de dados. quando for mostrar ,basta recuperar o caminho pelo banco de dados.

Se quiser um outro servidor, na Amazon para hospedar arquivos no S3 é ridiculamente barato e a API deles é bem fácil de utilizar.

por ex:

<p:ring value="#{imagemMb.listagem}" var="exame" styleClass="image-ring" easing="easeInOutBack">
	<p:graphicImage value="#{exame.dsDiretorio}\#{exame.dsNome}" width="100%" height="100%"/>	
</p:ring>

no banco o caminho está salvo dessa forma
ID; NOME; OID; DIRETORIO;
56;“cozinha 01.jpg”;56596;“C:\Desenvolvimento\projetos\HUAP-Endometriose\exames-imagem”

mostra que tem um resultado do banco porém não mostra a imagem…

E

Dá uma olhada nesse link que tem um passo a passo de como fazer.

F

Erick estou usando JBOSS as 7.1.1 =///

já tinha visto essa solução para Tomcat.

E

Putz, então nem posso ajudar, achei que a solução era mais genérica.
E o que acha de colocar a imagem em um site proprio para imagens? Não é viável para o projeto? Se for posso até postar uma exemplo de como enviar pra o AmazonS3 com o primefaces.

F

ErickRAR:
Putz, então nem posso ajudar, achei que a solução era mais genérica.
E o que acha de colocar a imagem em um site proprio para imagens? Não é viável para o projeto? Se for posso até postar uma exemplo de como enviar pra o AmazonS3 com o primefaces.

Você diz um ftp?

Posso tentar sim…vou ver aqui como que faço pra criar um ftp e tals… se puder postar o código, fico grato =)

e vlw pela ajuda…=P

E

Isso. No Amazon é de graça, só paga se passar do limite de requisições, o que , dependendo do sistema ,é bem dificil ultrapassar.

O método:

public void enviaImagem(FileUploadEvent event) {
	String linkDaImagem = "";
		try {
                  linkDaImagem = AmazonS3FileUpload.upload(event);
                  System.out.println(linkDaImagem);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
	}

E a classe:

package util;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;


import org.primefaces.event.FileUploadEvent;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.Region;

public class AmazonS3FileUpload {

	private static AmazonS3 s3;
	private final static String S3WAWSURL = "https://s3-sa-east-1.amazonaws.com/%s/%s";
	private final static String S3_BUCKETNAME="nome_do_bucket"; 

	static{
		InputStream credentials = AmazonS3FileUpload.class.getClassLoader().getResourceAsStream("AwsCredentials.properties");
		PropertiesCredentials awsCredentials = null;
		if(credentials == null)
			try {
				awsCredentials = new PropertiesCredentials(credentials);
			} catch (IOException e) {
				e.printStackTrace();
			}
		s3 = new AmazonS3Client(awsCredentials);
	}


	public static String uploadFoto(FileUploadEvent event) throws IOException{
		String fileName = URLEncoder.encode(event.getFile().getFileName(),"UTF-8");
		PutObjectRequest request = new PutObjectRequest(S3_BUCKETNAME, fileName, event.getFile().getInputstream(), getMetaData(event));
		s3.putObject(request.withCannedAcl(CannedAccessControlList.PublicRead));
		return new URL(String.format(S3WAWSURL,S3_BUCKETNAME,fileName)).toExternalForm(); 
	}
	
	private static ObjectMetadata getMetaData(FileUploadEvent event){
		ObjectMetadata metaData = new ObjectMetadata();
		metaData.setContentLength(event.getFile().getSize());
		metaData.setContentType(event.getFile().getContentType());
		return metaData;
	}
}

O AwsCredentials.properties você coloca em resources, com a secretKey e accessKey.

Pra separar por pasta, basta colocar o nome da pasta antes do URLEncoder:

String fileName = "nomeDaPasta/" + URLEncoder.encode(event.getFile().getFileName(),"UTF-8");

Aqui tem o jar: http://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk/1.8.3

Criado 20 de novembro de 2010
Ultima resposta 11 de jul. de 2014
Respostas 22
Participantes 9