Tutorial - Upload de Arquivos com Struts 2

Pessoal,

Muita gente tem perguntado como fazer upload com struts 2, então Guilherme Mello perguntou se não dava para eu postar um totorial no forum, entao vamos lá.

1 - Primeiramente deve-se importar os jar’s commons-fileupload-1.1.1.jar e o commons-io-1.1.jar para sua libraries.

2 - Se você não possui um arquivo struts-default.properties vc deve cria-lo no mesmo diretorio em que esta o arquivo struts.xml

Nesse arquivo struts-default.properties vc deve setar os seguintes parametros:

struts.multipart.parser=jakarta //Para utilizar as libs da apache
struts.multipart.maxSize=2097152 //seta o tamanho maximo do upload
#struts.multipart.saveDir=D:/uploads/ //Seta a pasta padrão para o upload dos arquivos, desabilitei esta linha pois setaremos a pasta via código

Não é obrigatório setar os parâmetros acima no arquivo struts.properties, pois por padrão o Struts 2 utliza o Jakarta como parser. Dessa forma basta apenas realizar a cópia do arquivo para uma pasta.

3 - Criaremos o arquivo “upload.jsp” com o seguinte formulario:


<s:form action="doUpload" method="POST" enctype="multipart/form-data">
         <s:file name="upload" label="File"/>        
         <s:submit />
     </s:form>

4 - Agora vamos Criar nossa Action, no meu caso criei dentro da pakage portaljava


public class FileUploadAction extends ActionSupport {

    private File upload; 
    private String uploadFileName; //nome do arquivo enviado
    private String uploadContentType; //contexto do arquivo, imagem, txt etc...    
    
    public File getUpload() {
        return upload;
    }
    
    public String moveArquivo(){
        
        copyFile(upload, new File("c:\\uploads\\"+ uploadFileName)); 
        
        return "SUCCESS";
    }
    
    // Metodo que move o arquivo para o diretorio desejado
 
    private static void copyFile(File in, File out) {
        
        try {
            FileChannel sourceChannel = new FileInputStream(in).getChannel();
            FileChannel destinationChannel = new FileOutputStream(out).getChannel();
            sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
            sourceChannel.close();
            destinationChannel.close();
        } catch (IOException ex) {
            ex.printStackTrace(); 
        }
    }
    
    
    public void setUpload(File upload) {
        this.upload = upload;
    }

    public String getUploadFileName() {
        return uploadFileName;
    }

    public void setUploadFileName(String uploadFileName) {
        this.uploadFileName = uploadFileName;
    }

    public String getUploadContentType() {
        return uploadContentType;
    }

    public void setUploadContentType(String uploadContentType) {
        this.uploadContentType = uploadContentType;
    } 

}

5 - Agora vamos configurar o struts.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<package name="portaljava" extends="struts-default" >
        
        <action name="upload" class="portaljava.FileUploadAction" method="input">
			<result>upload.jsp</result>
		</action>

        <action name="doUpload" class="portaljava.FileUploadAction" method="upload">
        	<result name="input">upload.jsp</result>
			<result>upload-success.jsp</result>
		</action>
				
    </package>
</struts>

6 - Agora pra finalizar vamos criar a pagina upload-success.jsp que mostrará o resultado da transferencia.


<%@ page 
	language="java" 
	contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>Exemplo Upload - Portal Java</title>
</head>

<body>
<h1>File Upload</h1>

<p>
    <ul>
        <li>ContentType: <s:property value="uploadContentType" /></li>
        <li>FileName: <s:property value="uploadFileName" /></li>
        <li>File: <s:property value="upload" /></li>
    </ul>
</p>

</body>
</html>

É isso ai pessoal, espero ter contribuido com a comunidade.

[], Paulo

Bem legal. Parabéns :wink:

opa.

estou fazendo exatamente isso que diz nesse tutorial,

mas na linha

copyFile(upload, new File(“c:\uploads\”+ uploadFileName));

surge um erro dizendo pra eu configurar o Build Path.

Eu adicionei as bibliotecas commons-fileupload-1.1.1.jar e commons-io-1.1.jar , como diz no tutorial, mas parece faltar mais alguma.

Alguém sabe onde pode estar o erro?
obrigado.

vc configurou o struts-default.properties como no exemplo?

Paulo, você sabe onde configuro a chave para exibir uma mensagem customizada, quando o tamanho do arquivo ultrapassar o tamanho permitido ?

A chave é:
struts.messages.error.file.too.large=File too large!

Paulo, eu criei o arquivo struts-default.properties na mesma pasta que está o struts.xml , e simplesmente copiei aquelas 3 linhas para o arquivo.

Por acaso, as bibliotecas commons-fileupload-1.1.1.jar e commons-io-1.1.jar não dependem de alguma outra para funcionar ?

no meu projeto estão as seguintes bibliotecas:

commons-fileupload-1.1.1.jar
commons-io-1.1.jar
commons-logging-1.0.4.jar
freemarker-2.3.8.jar
mysql-connector-java-5.1.5-bin.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xwork-2.0.4.jar

[quote=zembrzuski]Paulo, eu criei o arquivo struts-default.properties na mesma pasta que está o struts.xml , e simplesmente copiei aquelas 3 linhas para o arquivo.

Por acaso, as bibliotecas commons-fileupload-1.1.1.jar e commons-io-1.1.jar não dependem de alguma outra para funcionar ?

no meu projeto estão as seguintes bibliotecas:

commons-fileupload-1.1.1.jar
commons-io-1.1.jar
commons-logging-1.0.4.jar
freemarker-2.3.8.jar
mysql-connector-java-5.1.5-bin.jar
ognl-2.6.11.jar
struts2-core-2.0.11.jar
xwork-2.0.4.jar[/quote]

O properties e o struts.xml estão no classpath ? eles precisam estar lá para poder rodar a aplicação.

Pessoal, obrigado pela ajuda.

Eu estava usando, para a classe File, o org.apache.struts2.components.File , e dava aquele erro (para mudar algo no Build Path). Consegui solucionar o problema usando o java.io.File.

Sou iniciante em struts2. Então, fica aqui outra dúvida.

No tutorial, diz para setar o struts.xml da seguinte forma:
<action name=“doUpload” class=“portaljava.FileUploadAction” method=“upload”>

mas na classe FileUploadAction tem apenas o método
public String moveArquivo(){

o nome do método, nesse caso, não deveria ser upload tb?

Elas não são obrigadas a ter o método execute(), porque elas herdam esse método da classe ActionSupport. Para você utilizar qualquer método declarado na action como uma action independente, vc deve usar o atributo “method” na declaração da action no arquivo struts.xml.

mas então tem um erro no tutorial:

ele diz pra setar o struts.xml da seguinte forma:

mas na classe FileUploadAction não existe esse método, existe esse:
public String moveArquivo()

[quote=zembrzuski]mas então tem um erro no tutorial:

ele diz pra setar o struts.xml da seguinte forma:

mas na classe FileUploadAction não existe esse método, existe esse:
public String moveArquivo()

[/quote]

Exato.

Então tá, obrigado pela ajuda!

De nada. Qualquer dúvida ou idéia sobre como melhorar o tutorial, deixe uma mensagem aqui :wink:

Olá pessoal, to tentando fazer upload de imagem seguindo esse tutorial porem tá dando uma exception:

java.lang.NullPointerException
	java.io.FileInputStream.<init>(FileInputStream.java:103)
	br.com.ibooker.action.AdicionaLivroAction.copyfile(AdicionaLivroAction.java:34)
	br.com.ibooker.action.AdicionaLivroAction.execute(AdicionaLivroAction.java:27)

Segue as classes:

@Entity
public class Livros {
	@Id
	@GeneratedValue
	private Long id ;
	private String nome ;
	private File upload ;
	private String categoria ;
	private String descricao ;
	private Double preco ;
	private int codigo ;
	
       //getters and setters
	
}
public class AdicionaLivroAction {
	private Livros livro ;
	private File upload ;
	private String nomeImagem ;
	private String tipoImagem ;


	@Action(value="adicionaLivro", results={
			@Result(name="ok", location="/livro-adicionado.jsp")
	})
	public String execute() {
		copyfile(upload, new File("/home/desk/Documentos/uploads\\" + nomeImagem)) ;
		new LivrosDAO().adiciona(livro) ;
		return "ok" ;
	}
	
	private static void copyfile(File in, File out) {
		try {
			FileChannel sourceChannel = new FileInputStream(in).getChannel() ;
			FileChannel destinationChannel = new FileOutputStream(out).getChannel() ;
			sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel) ;
			sourceChannel.close() ;
			destinationChannel.close() ;
		}
		catch (IOException e) {
			e.printStackTrace() ;
		}
	}
        
        // getters and setters
	
}
<form action="adicionaLivro" method="post">
	Nome: <input type="text" name="livro.nome"> <br>
	Preço: <input type="text" name="livro.preco"> <br>
	Imagem: <input type="file" name="livro.upload"> <br>
	Categoria: <input type="text" name="livro.categoria"> <br>
	Código: <input type="text" name="livro.codigo"> <br>
	Descrição: <br>
	<textarea rows="3" cols="50" name="livro.descricao"></textarea> <br>
	<input type="submit" value="Adicionar">
</form>

[quote=desk]Olá pessoal, to tentando fazer upload de imagem seguindo esse tutorial porem tá dando uma exception:

java.lang.NullPointerException
	java.io.FileInputStream.<init>(FileInputStream.java:103)
	br.com.ibooker.action.AdicionaLivroAction.copyfile(AdicionaLivroAction.java:34)
	br.com.ibooker.action.AdicionaLivroAction.execute(AdicionaLivroAction.java:27)

Segue as classes:

@Entity
public class Livros {
	@Id
	@GeneratedValue
	private Long id ;
	private String nome ;
	private File upload ;
	private String categoria ;
	private String descricao ;
	private Double preco ;
	private int codigo ;
	
       //getters and setters
	
}
public class AdicionaLivroAction {
	private Livros livro ;
	private File upload ;
	private String nomeImagem ;
	private String tipoImagem ;


	@Action(value="adicionaLivro", results={
			@Result(name="ok", location="/livro-adicionado.jsp")
	})
	public String execute() {
		copyfile(upload, new File("/home/desk/Documentos/uploads\\" + nomeImagem)) ;
		new LivrosDAO().adiciona(livro) ;
		return "ok" ;
	}
	
	private static void copyfile(File in, File out) {
		try {
			FileChannel sourceChannel = new FileInputStream(in).getChannel() ;
			FileChannel destinationChannel = new FileOutputStream(out).getChannel() ;
			sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel) ;
			sourceChannel.close() ;
			destinationChannel.close() ;
		}
		catch (IOException e) {
			e.printStackTrace() ;
		}
	}
        
        // getters and setters
	
}

[code]

Nome:
Preço:
Imagem:
Categoria:
Código:
Descrição:

[/code][/quote]

Resolveu isso? Estamos com o mesmo problema. A aplicação faz deploy (joga na pasta temporária do JBoss) mas a referência de file vem nula (não faz o set do arquivo).

Paz e bem!

tenta colocar enctype=“multipart/form-data” no form

Aproveitando o assunto sobre upload no struts 2, alguem sabe como validar o tamanho do arquivo no struts 1?

Alguém poderia me ajudar como faço para pegar o caminho inteiro do arquivo? Tipo “C:\dados\empresa.xls”?

Vlw!

Java_Onslaught

[quote=java_onslaught]Alguém poderia me ajudar como faço para pegar o caminho inteiro do arquivo? Tipo “C:\dados\empresa.xls”?

Vlw!

Java_Onslaught[/quote]

Olha no struts 1 não tem como pegar no FormFile. Mas quando eu precisei fazer isso, eu usei js e capturei a string do <html:file pelo pelo id e passei pelo form:


uploadPath = document.getElementById("uploadId").getAttribute("value");
document.processoForm.pathArquivo.value = uploadPath;

Mas olha, se você quer fazer só um upload simples, não é necessário o path, no formfile já tem tudo o que você precisa,nome, tamanho,bytes…

vlw!! vou tentar via js!!

abs