Vraptor 3 - Cadastro + upload de Arquivo

9 respostas
ZEITGEIST

Bom dia Galera, estou com uma plena dúvida em como um cadastro de arquivos, o cadastro com o nome, descrição e etc.. ele realiza, a minha maior dúvida é que ele nao consegue fazer o upload do arquivo. Vou portar o código todo, vai se longo, mais para ficar mais claro a idéia.

Aqui é o Model do Documentos

package br.com.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;

import br.com.caelum.vraptor.ioc.Component;


@Entity
@Component
public class Documentos {
	
	@Id
	@SequenceGenerator(name = "sequence_documentos", sequenceName = "sequence_documentos", initialValue = 1, allocationSize = 1)
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence_documentos")
	private Long id;
	
	@Column(nullable=true)
    private String titulo;
	
	@Column(nullable=true)
	private String descricao;
	
	@Column(nullable=true)
	private String arquivo;

	public Documentos() {}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getTitulo() {
		return titulo;
	}

	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	public String getArquivo() {
		return arquivo;
	}

	public void setArquivo(String arquivo) {
		this.arquivo = arquivo;
	}
	
	
	
}

Aqui é o DocumentosController

package br.com.controller;

import java.util.List;



import br.com.branet.sias.arquivos.Arquivos;
import br.com.branet.sias.dao.DocumentosDao;
import br.com.branet.sias.model.Documentos;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;

import br.com.caelum.vraptor.validator.ValidationMessage;
import br.com.caelum.vraptor.view.Results;

@Resource
public class DocumentosController {
	
	public final Validator validator;
	public final Result result;
	public final DocumentosDao dao;
	public final Arquivos arquivo;
	
	public DocumentosController(Validator validator, Result result,
			DocumentosDao dao, Arquivos arquivo) {
		this.validator = validator;
		this.result = result;
		this.dao = dao;
		this.arquivo = arquivo;
	}
	@Get @Path("/documentos/novo")
	public void adicionar() {
		
	}
	
	@Get @Path("/documentos/list")	
	public List<Documentos> list() {
		return dao.listAll();
	}
	
	@Get @Path("/documentos/{id}")
	public Documentos adicionar(Long id){
		return (Documentos) dao.carrega(id);
	}
	
	@Path("/documentos/{documentos.id}")
	@Post
	public void update(Documentos documentos) {
		if (documentos.getTitulo() == null || documentos.getTitulo().length() == 0) {
			validator.add(new ValidationMessage(
					"Informe o titulo do documento.", ""));
		}
		if (documentos.getDescricao() == null || documentos.getDescricao().length() == 0) {
			validator.add(new ValidationMessage(
					"Informe a descricao do documento.", ""));
		}		
		
		validator.onErrorUse(Results.logic()).forwardTo(DocumentosController.class).adicionar();

		dao.update(documentos);
		result.include("notice", "Documento alterado com sucesso.");
	    result.use(Results.logic()).redirectTo(DocumentosController.class).list();
		
	}
	
	@Path("/documentos")
	@Post
	public void salvar(Documentos documentos){
		if (documentos.getDescricao() == null || documentos.getDescricao().length() == 0) {
			validator.add(new ValidationMessage(
					"Informe a descricao do documento.", ""));
		} 
		
		validator.onErrorUse(Results.logic()).forwardTo(DocumentosController.class).adicionar();
		dao.add(documentos);
        result.include("notice", "Documento adicionado(a) com sucesso.");
	    result.use(Results.logic()).redirectTo(DocumentosController.class).list();
	}
	

	@Path("/documentos/del/{documentos.id}")
	@Get
	public void remove(Documentos documentos){
		Documentos doc  = (Documentos) dao.carrega(documentos.getId());
		dao.remove(doc);
		result.include("notice", "Documento excluido com sucesso.");
		result.redirectTo(DocumentosController.class).list();
	}
	

}

Aqui é o DocumentosDao e em seguida o DefaultDocumentosDao

package br.com.dao;

import java.util.List;


import br.com.branet.sias.model.Documentos;

public interface DocumentosDao {
	
	
	Documentos carrega (Long id);
	
	void add(Documentos documentos);
	
	void refresh(Documentos documentos);
	
	void update(Documentos documentos);
	
	void remove(Documentos documentos);
	
	List<Documentos> listAll();

}
package br.com.dao;

import java.util.List;

import org.hibernate.Session;

import br.com.branet.sias.model.Documentos;
import br.com.caelum.vraptor.ioc.Component;


@Component
public class DefaultDocumentosDao implements DocumentosDao{

	private Session session;
	
	public DefaultDocumentosDao (Session session) {
		this.session = session;
	}
	
	public void add(Documentos documentos) {		
		this.session.save(documentos);
	}

	
	public Documentos carrega(Long id) {
		return (Documentos) this.session.load(Documentos.class, id);
	
	}

	@SuppressWarnings("unchecked")
	public List<Documentos> listAll() {
		return session.createCriteria(Documentos.class).list();
	}

	
	public void refresh(Documentos documentos) {
		this.session.refresh(documentos);		
	}

	public void remove(Documentos documentos) {
		this.session.delete(documentos);
		
	}
	
	public void update(Documentos documentos) {
		this.session.update(documentos);
		
	}
	
	

}

Este é a classe Arquivos do pacote Arquivos:

package br.com.arquivos;

import java.io.File;

import javax.naming.directory.DirContext;
import javax.servlet.ServletContext;
import org.apache.commons.io.IOUtils;
import java.io.FileOutputStream;
import java.io.IOException;


import br.com.branet.sias.model.Documentos;
import br.com.caelum.vraptor.interceptor.multipart.UploadedFile;
import br.com.caelum.vraptor.ioc.Component;

;

@Component
public class Arquivos {
	
	
	private File pastaArquivos;
	
	public Arquivos(ServletContext context) {
		String caminhoArquivo = context.getRealPath("WEB-INF/arquivos");
		pastaArquivos = new File(caminhoArquivo);
		pastaArquivos.mkdir();
	}
	
	public void salvar(UploadedFile arquivo, Documentos documentos) {
		File destino = new File(pastaArquivos, documentos.getId() + ".arquivo");
		try {
			IOUtils.copyLarge(arquivo.getFile(), new FileOutputStream(destino));
		} catch (IOException e) {
			throw new RuntimeException("Erro ao copiar arquivo", e);
			}	
		
		}
	public File mostra(Documentos documentos) {
		return new File(pastaArquivos, documentos.getId() + ".arquivo");
	}
	

}

O ArquivosController:

package br.com.controller;

import java.io.File;

import br.com.branet.sias.arquivos.Arquivos;
import br.com.branet.sias.dao.DocumentosDao;
import br.com.branet.sias.model.Documentos;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.interceptor.multipart.UploadedFile;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.com.caelum.vraptor.validator.Validations;


@Resource
public class ArquivosController {
	
	private final Validator validator;
	private final Arquivos arquivos;
	private final Result result;
	private final DocumentosDao dao;
	
	public ArquivosController(Validator validator, Arquivos arquivos,
			Result result, DocumentosDao dao) {
		this.validator = validator;
		this.arquivos  = arquivos;
		this.result    = result;
		this.dao       = dao;
	}	   

	@Post @Path("/documentos/{documentos.id}/arquivo")
	public void upload(Documentos documentos, final UploadedFile arquivo) {
		validator.checking(new Validations() {{
			if (arquivo.getFile() == null) {
				validator.add(new ValidationMessage(
						"Informe o arquivo.", ""));
			}
			}});
		validator.onErrorRedirectTo(DocumentosController.class).list();
		
		dao.add(documentos);
		arquivos.salvar(arquivo, documentos);
		result.redirectTo(DocumentosController.class).list();
	}
	
	@Get 
	@Path("/documentos/{documentos.id}/arquivo")
	public File download(Documentos documentos) {
		return arquivos.mostra(documentos);
	}

}

E por fim a View:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@include file="/menuAd.jsp"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.Date"%>
<%@page import="java.text.Format"%>
<%@page import="java.util.Calendar"%>



<div class="onecolumn" style="width: 50%;position: absolute;right: 30%;left: 35%;">
<div class="header"><span><c:choose>
	<c:when test="${empty documentos.id}">Novo</c:when>
	<c:otherwise>Edi&ccedil&atilde;o de </c:otherwise>
</c:choose>Documento</span></div>
<br class="clear" />
<div class="content">	
<c:choose>
    <c:when test="${empty documentos.id}"><form action="<c:url value="/documentos" />" name="registerForm"	method="post" enctype="multipart/form-data"></c:when>
	<c:otherwise><form action="<c:url value="/documentos/${documentos.id}" />" name="registerForm" method="post" enctype="multipart/form-data"></c:otherwise>
</c:choose>
		
	<c:if test="${not empty errors}">
	<div class="alert_error">
		<p>			
			<c:forEach items="${errors}" var="error">
				<img src="/sias/images/icon_error.png" alt="delete" class="mid_align"/>
				${error.category} - ${error.message}<br />
			</c:forEach>
		</p>
	</div>
</c:if>
<input  type="hidden" name="documentos.id" value="${documentos.id}" />

<table width="100%" border="0">

<tr>
	<td></td>
</tr>
<tr>
	<td><b>Titulo:</b><span style="color: red;">*</span></td>
</tr>
<tr>
	<td><input type="text" name="documentos.titulo" value="${documentos.titulo}" style="width: 200px;"/></td>
</tr>

<tr>
		<td>
			<fieldset>
				<legend><b>Arquivo</b></legend>
				<input type="file" name="arquivo" />
			</fieldset>
		</td>
</tr>
<tr>
	<td><b>Descri&ccedil;&atilde;o:</b><span style="color: red;">*</span></td>
</tr>
<tr>
	<td>
		<textarea style="width:200px;" name="documentos.descricao">${documentos.descricao}</textarea>
	</td>
</tr>
  <tr>
     <td>
    	<br />
    	<c:choose>
			<c:when test="${empty documentos.id}">

			<input type="submit" value="Cadastrar" /><input type="reset" value="Limpar" />

			</c:when>
			<c:otherwise>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

				<input type="submit" value="Editar" /><input type="reset" value="Restaurar" />

			</c:otherwise>
		</c:choose>
    </td>
  </tr>
</table></div></div>

Bom, ai está todo o código que envolve o processo, ele nao esta salvando o arquivo na pasta especificada. Fico no aguardo por uma Luz.
Obrigado!

9 Respostas

Lucas_Cavalcanti

vc está com o commons-fileupload no classpath?

ZEITGEIST

Sim Lucas, estou.

Lucas_Cavalcanti

dá algum erro? dá erro de validação? vc tentou copiar o arquivo.getFile() para algum lugar? (é mto código que vc postou, não li tudo)

ZEITGEIST

Não dá erro nenhum, eu estou tentando mandar o arquivo para a pasta “WEB-INF/arquivos”, eu faço isso na classe Model Arquivos, e simplesmente o arquivo não aparece lá, ja mudei o caminho varias vezes, mais o caminho está correto.

Lucas_Cavalcanti

tenta ver se o

context.getRealPath("WEB-INF/arquivos")

tá retornando o caminho correto

aparentemente não tem nada de errado com o código de copiar

ZEITGEIST

está retornando sim.
:slight_smile:

Lucas_Cavalcanti

então se veio algum conteúdo no arquivo, deveria funcionar normalmente…

habilita o log de debug do vraptor e veja se ele dá algum tipo de erro

ZEITGEIST

Lucas, o que eu achei de estranho foi essas duas linhas aqui:

13:44:21,000 DEBUG [OgnlParametersProvider] Applying arquivo with [alteracao.txt]
13:44:21,000 DEBUG [OgnlParametersProvider] cant find property for expression arquivo ignoring

O aleracao.txt é o arquivo que tento upar, mais verifiquei novamente o getFile() e ele nao vem vazio. oO

Alguma sugestão?

Lucas_Cavalcanti

tenta imprimir o conteúdo do arquivo:

System.out.println(new Scanner(arquivo.getFile()).useDelimiter("$$").next()));

se isso funcionar, tem que ver o código que copia o arquivo mesmo… tipo tenta trocar o IOUtils.copyLarge por só copy, fechar os streams, e coisas do tipo

Criado 2 de maio de 2011
Ultima resposta 2 de mai. de 2011
Respostas 9
Participantes 2