Upload de imagens com VRaptor

Pessoal to fazendo o ex. da caelum da apostila fj28, mas estou com problemas, vi em outros topicos mas nao consigo resolver o problema, não consigo fazer o upload da imagem, da o seguinte erro:

GRAVE: Servlet.service() for servlet default threw exception br.com.caelum.vraptor.InterceptionException: java.lang.IllegalArgumentException: java.io.FileNotFoundException: C:\Users\Rafael\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\goodbuy\WEB-INF\img\10.imagem (O sistema não pode encontrar o arquivo especificado)

sei que o erro já diz tudo mas nao consigo resolver.

package br.com.caelum.goodbuy.controller;

import java.io.File;

import br.com.caelum.goodbuy.imagens.Imagens;
import br.com.caelum.goodbuy.modelo.Produto;
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.Validations;
import static org.hamcrest.Matchers.*;

import static br.com.caelum.vraptor.view.Results.*;

@Resource
public class ImagensController {

	private final Validator validator;
	private final Imagens imagens;
	private final Result result;

	public ImagensController(Validator validator, Imagens imagens, Result result) {
		this.validator = validator;
		this.imagens = imagens;
		this.result = result;
	}

	@Post
	@Path("/produtos/{produto.id}/imagem")
	public void upload(Produto produto, final UploadedFile imagem) {
		validator.checking(new Validations() {
			{
				if (that(imagem, is(notNullValue()), "imagem", "imagem.nula")) {
					that(imagem.getContentType(), startsWith("imagem"),
							"imagem", "nao.eh.imagem");
				}
			}
		});
		validator.onErrorUse(logic()).redirectTo(ProdutosController.class)
				.edita(produto.getId());

		imagens.Salva(imagem, produto);
		result.redirectTo(ProdutosController.class).edita(produto.getId());
	}

	@Get
	@Path("/produtos/{produto.id}/imagem")
	public File download(Produto produto) {
		return imagens.mostra(produto);
	}
}

package br.com.caelum.goodbuy.imagens;

import java.io.File;
import java.io.FileOutputStream;

import javax.servlet.ServletContext;

import org.apache.commons.io.IOUtils;

import br.com.caelum.goodbuy.modelo.Produto;
import br.com.caelum.vraptor.interceptor.multipart.UploadedFile;
import br.com.caelum.vraptor.ioc.Component;

@Component
public class Imagens {

	private File pastaImagens;

	public Imagens(ServletContext context) {
		String caminhoImagens = context.getRealPath("/WEB-INF/img");
		pastaImagens = new File(caminhoImagens);
		pastaImagens.mkdir();
	}

	public void Salva(UploadedFile imagem, Produto produto) {
		File destino = new File(pastaImagens, produto.getId() + ".imagem");

		try {
			IOUtils.copyLarge(imagem.getFile(), new FileOutputStream(destino));
		} catch (Exception e) {
			throw new RuntimeException("Erro ao copiar imagem", e);
		}
	}

	public File mostra(Produto produto) {
		return new File(pastaImagens, produto.getId() + ".imagem");
	}

}

Desde já agradeço a ajuda…

tenta, ao invés de salvar dentro de WEB-INF/img, salvar em alguma pasta física do sistema, tipo: C:\Imagens

Já tentei, da o mesmo erro…

Caused by: java.lang.IllegalArgumentException: java.io.FileNotFoundException: C:\Users\Rafael\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\goodbuy\D:\img\6.imagem (A sintaxe do nome do arquivo, do nome do diretório ou do rótulo do volume está incorreta)

faz assim:

pastaImagem = new File("C:\Imagens");

ou seja, sem o context.getRealPath()

Hmm, qual a versão do vraptor que você está usando?

estou usando a ultima versão… mais agora o problema não é mas o endereço, se eu colocar a imagem na pasta, esta sendo exibida na aplicação, porem ainda não consigo fazer o upload… vou mexer em mais alguma coisa aki e posto o resultado se positivo ou nao…

Vlw…

Hmm, desconfio de uma coisa. Você está usando em qual sistema operacional o site, e em qual sistema operacional você acessa o site?

Windows 7… :frowning:

Hmm, na documentação do infame commons-io não diz se o método FileUtils.copyLarge cria o arquivo caso ele não existir.

Use o mesmo código que você postou lá no inicio da classe Imagens, porém adicione a linha abaixo logo após a declaração de File destino.

destino.createNewFile()

Mesmo com a boa vontade de vcs me ajudarem…

Ainda nao teve jeito, eu estou burrando em algun lugar… quando eu coloco a imagem na pasta mostra normal, mas o upload nao faz de jeito maneira… Qualquer coisa vou tirar a Libs e postar o projeto completo do FJ28…

Vlw

Você pode mandar o stacktrace quero saber quem está lançando essa exception.

ainda tá dando FileNotFound ou só não tah copiando?

Depois que vc falou para eu mudar o caminho, ficou blz, coloquei uma foto lá com o id do produto e e ta exibindo direitinho, mas o upload para a pasta no sistema nao faz nem a pau…

Eu sei que deve ser erro idiota, mas nao consigo enchergar…

da o seguinte erro agora.

HTTP Status 405 -

type Status report

message

description The specified HTTP method is not allowed for the requested resource ().
Apache Tomcat/6.0.26

mas se eu der enter no endereço no browser exibe a foto antiga, mas nao troca pela nova…(não manda para a pasta :frowning: )

Vlw

405 quer dizer que vc tah usando o método errado…

sua lógica tá anotada com @Get ou @Post, ou algo do tipo?

O controller ta assim

package br.com.caelum.goodbuy.controller;

import java.io.File;
import java.io.IOException;

import br.com.caelum.goodbuy.imagens.Imagens;
import br.com.caelum.goodbuy.modelo.Produto;
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.Validations;
import static org.hamcrest.Matchers.*;

import static br.com.caelum.vraptor.view.Results.*;

@Resource
public class ImagensController {

	private final Validator validator;
	private final Imagens imagens;
	private final Result result;

	public ImagensController(Validator validator, Imagens imagens, Result result) {
		this.validator = validator;
		this.imagens = imagens;
		this.result = result;
	}

	@Post
	@Path("/produtos/{produto.id}/imagem")
	public void upload(Produto produto, final UploadedFile imagem)
			throws IOException {
		validator.checking(new Validations() {
			{
				if (that(imagem, is(notNullValue()), "imagem", "imagem.nula")) {
					that(imagem.getContentType(), startsWith("image"),
							"imagem", "nao.eh.imagem");
				}
			}
		});
		validator.onErrorUse(logic()).redirectTo(ProdutosController.class)
				.edita(produto.getId());

		imagens.Salva(imagem, produto);
		result.redirectTo(ProdutosController.class).edita(produto.getId());
	}

	@Get
	@Path("/produtos/{produto.id}/imagem")
	public File download(Produto produto) {
		return imagens.mostra(produto);
	}
}

e o Imagens está assim

package br.com.caelum.goodbuy.imagens;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.servlet.ServletContext;

import org.apache.commons.io.IOUtils;

import br.com.caelum.goodbuy.modelo.Produto;
import br.com.caelum.vraptor.interceptor.multipart.UploadedFile;
import br.com.caelum.vraptor.ioc.Component;

@Component
public class Imagens {

	private File pastaImagens;

	public Imagens(ServletContext context) {
		//String caminhoImagens = context.getRealPath("/D:/img");
		pastaImagens = new File("d:/img");
		pastaImagens.mkdir();
	}

	public void Salva(UploadedFile imagem, Produto produto) throws IOException {
		File destino = new File(pastaImagens, produto.getId() + ".jpg");
		destino.createNewFile() ;

		try {
			IOUtils.copyLarge(imagem.getFile(), new FileOutputStream(destino));
		} catch (Exception e) {
			throw new RuntimeException("Erro ao copiar imagem", e);
		}
	}

	public File mostra(Produto produto) {
		return new File(pastaImagens, produto.getId() + ".jpg");
	}

}

Esse upload ta dando pano para manga. :frowning:

Obrigado pela atenção …

e o form de upload?

Opa… ta aki…

<form action="<c:url value="/produtos/${produto.id}/imagem"/>" method="POST" enctype="multpart/form-data">
	<fieldset>
		<legend>Editar Produto</legend>
		
		<label for ="nome">Nome:</label>
		<input id="nome" type="text" name="produto.nome" value="${produto.nome}" />
		
		<label for ="descicao">Descricao:</label>
		<textarea id ="descricao" name="produto.descricao">${produto.descricao}</textarea>
		
		<label for ="preco">Preco:</label>
		<input id="preco" type="text" name="produto.preco" value="${produto.preco}" />
		
		
		
	</fieldset>	

<fieldset>
	<legend>Upload de imagem</legend>
	<img src="<c:url value="/produtos/${produto.id }/imagem"/>" width="100" height="100"></img>
	<input type="file" name="imagem" />
	<button type="submit" name="_method" value="PUT">Alterar</button>
</fieldset>
</form>

Enquanto não tivermos o stacktrace vamos só ficar brincando de adivinhar o problema.

no

<button type="submit" name="_method" value="PUT">Alterar</button>

tire o name e o value:

<button type="submit">Alterar</button>

:frowning: