Upload com vraptor3 + uploadify [resolvido]

Sim Lucas, commons-io-1.3.2.jar e commons-fileupload-1.2.1.jar.

upload de um arquivo só funciona então?

Isso mesmo, funciona perfeitinho, mas so recebo um arquivo.

testei aqui no blank-project e funcionou:

<form action="" method="post" enctype="multipart/form-data">
	<input type="file" name="arquivos[0]"> 
	<input type="file" name="arquivos[1]">
	<input type="submit"> 
</form>
	@Path("/")
	public void index(List<UploadedFile> arquivos) {
		//...
	}

vc está usando algo parecido com isso?

[quote=Lucas Cavalcanti]testei aqui no blank-project e funcionou:

<form action="" method="post" enctype="multipart/form-data">
	<input type="file" name="arquivos[0]"> 
	<input type="file" name="arquivos[1]">
	<input type="submit"> 
</form>
	@Path("/")
	public void index(List<UploadedFile> arquivos) {
		//...
	}

vc está usando algo parecido com isso?[/quote]

Hummmm não Lucas, eu pensei que poderia fazer upload de vários arquivos de uma vez só, usando penas um único input file. Vou testar isso amanhã, mas pelo jeito terei que fazer upload de um número limitado de arquivos é isso?

vc pode criar um botão + que adiciona via javascript outro input file. No mesmo não rola.

outra saída é usar um plugin do jquery, como o uploadify http://uploadify.com

[quote=Lucas Cavalcanti]vc pode criar um botão + que adiciona via javascript outro input file. No mesmo não rola.

outra saída é usar um plugin do jquery, como o uploadify http://uploadify.com[/quote]

Pois é Lucas, por isso que postei nesse tópico, é exatamente esse plugin que estou tentando utilizar. Abaixo o script para chamar o uploadify.

<script type="text/javascript">
		$(function() {
			$("#arquivos").uploadify({
				  "uploader"       : '${pageContext.request.contextPath}/uploadify/uploadify.swf',
				  'script'         : '${pageContext.request.contextPath}/migracao/processarArquivos',
				  'cancelImg'      : '${pageContext.request.contextPath}/uploadify/cancel.png',
				  'buttonText'	   : 'Selecionar arquivos',
				  'folder'         : '${pageContext.request.contextPath}/uploads',
				  'multi'          : true,
				  'auto'           : false,
				  'fileExt'        : '*.pdf',
				  'fileDesc'       : 'Arquivos PDF (*.PDF)'
			});
			
			$("#envio").click(function(){
				$("#arquivos").uploadifyUpload();
			});
		});
		
</script>

No form estou fazendo assim:

<form enctype="multipart/form-data" method="post">
	<fieldset>
		<legend>Migrar documentos</legend>
		<label for="ano">Ano da publicação</label>
		<input type="text" id="ano" name="ano"/>
		
		<label for="ano">Categoria</label>
		<select id="categoria" name="categoria.id">
			<c:forEach var="categoria" items="${categorias}">
				<option value="${categoria.id}">${categoria.nome }</option>	
			</c:forEach>		
		</select>
		
		<label for="arquivos">Arquivos</label>
		<input type="file" id="arquivos" name="arquivos[]" >
		<button id="envio">Enviar</button>
	</fieldset>

</form>

e no controller:

public void processarArquivos(List<UploadedFile> arquivos, String ano, int categoraId){
		
		for(UploadedFile fd:arquivos){
			System.err.println(">>>>>>>>>>>>>>> "+fd.getFileName());
		}
		
		
}

entendi…

o uploadify não passa todos os arquivos de uma vez, e sim um por um…

por padrão o nome que ele usa é FileData. Vc pode sobrescrever esse nome com a option fileDataName:

$("#arquivos").uploadify({  
                  "uploader"       : '${pageContext.request.contextPath}/uploadify/uploadify.swf',  
                  'script'         : '${pageContext.request.contextPath}/migracao/processarArquivos',  
                  'cancelImg'      : '${pageContext.request.contextPath}/uploadify/cancel.png',  
                  'buttonText'     : 'Selecionar arquivos',  
                  'folder'         : '${pageContext.request.contextPath}/uploads',  
                  'fileDataName' : 'arquivo', 
                  'multi'          : true,  
                  'auto'           : false,  
                  'fileExt'        : '*.pdf',  
                  'fileDesc'       : 'Arquivos PDF (*.PDF)'  
            });  

e no controller:

public void processarArquivos(UploadedFile arquivo, String ano, int categoraId){

Lucas acredito que consegui achar o problema com meu código. Bastou devolver um objeto serializado que o uploadify funcionou corretamente. Entretanto vou ter que refatorar, pois não consigo receber outros dois parâmetros, nada muito difícil de resolver.

o controller ficou assim:

	public void processarArquivos(List<UploadedFile> arquivos, String ano, int categoriaId){
		
		for(UploadedFile fd:arquivos){
			System.err.println(">>>>>>>>>>>>>>> nome do arquivo:"+fd.getFileName());
		}
		
		result.use(Results.json()).from(arquivos).serialize();
		
	}

O HTML ficou assim:

<script type="text/javascript">
		$(function() {
			$("#arquivos").uploadify({
				  "uploader"       : '${pageContext.request.contextPath}/uploadify/uploadify.swf',
				  'script'         : '${pageContext.request.contextPath}/migracao/processarArquivos',
				  'cancelImg'      : '${pageContext.request.contextPath}/uploadify/cancel.png',
				  'buttonText'	   : 'Selecionar arquivos',
				  'folder'         : '${pageContext.request.contextPath}/uploads',
				  'fileDataName'   : 'arquivos', 
				  'multi'          : true,
				  'auto'           : false,
				  'fileExt'        : '*.pdf',
				  'fileDesc'       : 'Arquivos PDF (*.PDF)'
			});
			
			$("#envio").click(function(){
				$("#arquivos").uploadifyUpload();
			});
		});
		
</script>


<form enctype="multipart/form-data" method="post">

	<fieldset>
		<legend>Migrar documentos</legend>
		<label for="ano">Ano</label>
		<input type="text" id="ano" name="ano"/>
		
		<label for="ano">Categoria</label>
		<select id="categoria" name="categoriaId">
			<c:forEach var="categoria" items="${categorias}">
				<option value="${categoria.id}">${categoria.nome }</option>	
			</c:forEach>		
		</select>
		
		<label for="arquivos">Arquivos</label>
		<input type="file" id="arquivos" name="arquivos" >
		<a href="#" id="envio">Enviar</a>
		
	</fieldset>

</form>

Obrigado Lucas pela atenção, vc é sempre bastante atencioso com todos que buscam ajuda aqui. Um abração

Fiz deacordo o html e a controller acima mas no html da HTTP Error, nada no console.chega null na minha controller… falta algo?

qual é o seu código?

Claro, desculpa lucas, segue…

Fiz algumas tentativas…

pela controller do vraptor ficou assim…

meu jsp

    &lt;script type="text/javascript" src="jquery.uploadify-v2.1.4/jquery-1.4.2.min.js"&gt;&lt;/script&gt;
        &lt;script type="text/javascript" src="jquery.uploadify-v2.1.4/jquery.uploadify.v2.1.4.js"&gt;&lt;/script&gt;
        &lt;script type="text/javascript" src="jquery.uploadify-v2.1.4/jquery.uploadify.v2.1.4.min.js"&gt;&lt;/script&gt;
        &lt;script type="text/javascript" src="jquery.uploadify-v2.1.4/swfobject.js"&gt;&lt;/script&gt;

        &lt;script type="text/javascript"&gt;
		$(function() {
			$("#arquivos").uploadify({
				  "uploader"       : '${pageContext.request.contextPath}/jquery.uploadify-v2.1.4/uploadify.swf',
				  'script'         : '${pageContext.request.contextPath}/upload',
				  'cancelImg'      : '${pageContext.request.contextPath}/jquery.uploadify-v2.1.4/cancel.png',
				  'buttonText'	   : 'Selecionar arquivos',
				  'folder'         : '${pageContext.request.contextPath}/anexos',
				  'fileDataName'   : 'arquivos', 
				  'multi'          : true,
				  'auto'           : false
			});
			
			$("#envio").click(function(){
				$("#arquivos").uploadifyUpload();
			});
		});
         &lt;/script&gt;
 &lt;form enctype="multipart/form-data" method="post"&gt;

	&lt;fieldset&gt;
		&lt;input type="file" id="arquivos" name="arquivos" &gt;
		<a  >Enviar</a>
		
	&lt;/fieldset&gt;

&lt;/form&gt;

Meu controller esta assim, mas aki a lista ta null

	@Post @Path("/upload")
	public void processarArquivos(List&lt;UploadedFile&gt; arquivos){
		
		for(UploadedFile atquivo:arquivos){
			System.err.println(arquivo.getFileName());
		}
		
		result.use(Results.json()).from(arquivos).serialize();
		
	}

Tentei ainda por um Servlet assim:
Populo um HashMap que tem {folder=/userfiles/image, ac=upload, Upload=Submit Query, Filename=fidelis_felipe_2011.pdf, Filedata=fidelis_felipe_2011.pdf}

Mas minha List<FileItem> items permanece null depois de List<FileItem> items = upload.parseRequest(req);

O que devo estar fazendo de errado Lucas?

	System.out.println("UploadServlet invoked. Here are all uploaded files: ");
	        try {
	        	
	        	FileItemFactory factory = new DiskFileItemFactory();
				ServletFileUpload upload = new ServletFileUpload(factory);
	            List&lt;FileItem&gt; items = upload.parseRequest(req);
	            for (FileItem item : items) {
	                if (!item.isFormField()) {
	                    System.out.println("Name: " + item.getName());
	                    System.out.println("Size: " + item.getSize());
	                    System.out.println("Type: " + item.getContentType());
	                }
	            }
	        } catch (Exception ex) {
	            try {
					throw new ServletException(ex);
				} catch (ServletException ex2) {
					// TODO Auto-generated catch block
					ex2.printStackTrace();
				}
	        }

vc não pode criar o uploadServlet, o próprio vraptor vai fazer isso… se vc coloca o Servlet o vraptor não vai ter acesso ao upload.

Quero fazer mesmo pelo vraptor, esse servlet foi tentativa extra.

Levando em consideração que não tenho mais o servletes? minha list ta chegando null

troque a List por apenas UploadedFile

o uploadify vai mandar um arquivo por vez

Certo, funfou sim, pensei que ele mandava a lista.
Muito obrigado Lucas :smiley:

No meu caso está retornando um http status 302.

        <script type="text/javascript" src="${pageContext.request.contextPath}/javascripts/uploadify/swfobject.js"></script>

        <script type="text/javascript" src="${pageContext.request.contextPath}/javascripts/uploadify/jquery.uploadify.v2.1.4.js"></script>

        <script type="text/javascript">
            $(document).ready(function() {
                
                $('#file').uploadify({
                    'uploader'  : '${pageContext.request.contextPath}/javascripts/uploadify/uploadify.swf',
                    'script'    : '${pageContext.request.contextPath}/upload/',
                    'buttonText': 'Selecionar arquivos',  
                    'cancelImg' : '${pageContext.request.contextPath}/javascripts/uploadify/cancel.png',
                    'folder'    : '${pageContext.request.contextPath}/javascripts/upload',
                    'fileDataName': 'arquivos',
                    'multi'          : false,  
                    'auto'           : false,  
                    'onError'     : function (event,ID,fileObj,errorObj) {
                        alert(errorObj.type + ' Error: ' + errorObj.info);
                      }                    
                  });

                $('#enviar').click(function(e){
                    $('#file').uploadifyUpload();                	
                });
                
                
             });
            
        </script>
<form enctype="multipart/form-data" method="post">
	
    <input type="file" id="file" name="file" />
     <a id="enviar" href="#">Upload Files</a>            

</form>

Método do controller que não é chamado.

	@Post("/upload/")
	public void test(UploadedFile arquivos) {
		System.out.println(arquivos);
		System.out.println(">>>>>>>>>>>>>>");
		result.use(json()).from(arquivos).serialize();
	}

No console só aparece o log do CommonsUploadMultipartInterceptor.



INFO [CommonsUploadMultipartInterceptor] Request contains multipart data. Try to parse with commons-upload.

o flash usa uma sessão diferente da da página… então se vc tem algum interceptor de autenticação ele vai dar 302 (redirecionar pra página de login, por exemplo)…

vc precisa fazer umas maracutaias pro flash usar a mesma sessão que o browser, ou deixar a lógica de upload aberta (autenticada de outro jeito que não a sessão do usuário). Ex via uri: /upload/{idDoUsuario}/{hashAPartirDoIdDoUsuario}

Senhores

fiz da forma como eulen indicou porém ainda assim sem sucesso.
Diz que nao encontrou o arquivo flash uploadify.swf e dai nao abre a janela pra escolher os arquivos.

Eu tive que mudar apenas uma coisa, a forma como o formulario eh submetido, tirei o link e coloquei um botao de submit.

HTML:

<script type="text/javascript">  
            $(function() {  
                $("#arquivos").uploadify({  
                      "uploader"       : '${pageContext.request.contextPath}/uploadify/uploadify.swf',  
                      'script'         : '${pageContext.request.contextPath}/migracao/processarArquivos',  
                      'cancelImg'      : '${pageContext.request.contextPath}/uploadify/cancel.png',  
                      'buttonText'     : 'Selecionar arquivos',  
                      'folder'         : '${pageContext.request.contextPath}/uploads/',  
                      'fileDataName'   : 'arquivos',   
                      'multi'          : true,  
                      'auto'           : false,  
                      'fileExt'        : '*.pdf',  
                      'fileDesc'       : 'Arquivos PDF (*.PDF)'  
                });  
                  
                $("#envio").click(function(){  
                    $("#arquivos").uploadifyUpload();  
                });  
            });  
              
    </script>  
      
      
    <form enctype="multipart/form-data" method="post"  action="<c:url value="/forecast/up" />" >  
      
        <fieldset>  
            <legend>Migrar documentos</legend>  
            <label for="ano">Ano - ${pageContext.request.contextPath}/uploadify/uploadify.swf</label>  
            <input type="text" id="ano" name="ano"/>  
              
            <label for="ano">Categoria</label>  
            <input type="text" id="categoria" name="categoriaId"/>
              
            <label for="arquivos">Arquivos</label>  
            <input type="file" id="arquivos" name="arquivos" >  
            
            <input type="submit" value="<fmt:message key="forecast.add.submit"/>">
              
        </fieldset>  
      
    </form>  

alguma dica?

obrigado

Valeu lucas vou tentar implementar.