Erro no upload de imagem

Pessoal nao consigo achar onde está o erro na hora de fazer upload de uma imagem, veja o código controller:

package br.com.projeto.controller;

import java.io.File;
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 br.com.projeto.DTO.Produto;
import br.com.projeto.imagens.Imagens;
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);
	}
}	

e o erro que está dando:

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.multipart.MultipartInterceptor.intercept(MultipartInterceptor.java:98)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)

root cause

java.util.MissingResourceException: Can’t find bundle for base name messages, locale en_US
java.util.ResourceBundle.throwMissingResourceException(Unknown Source)
java.util.ResourceBundle.getBundleImpl(Unknown Source)
java.util.ResourceBundle.getBundle(Unknown Source)
br.com.caelum.vraptor.validator.Validations.(Validations.java:56)
br.com.projeto.controller.ImagensController$1.(ImagensController.java:34)
br.com.projeto.controller.ImagensController.upload(ImagensController.java:34)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:80)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.interceptor.multipart.MultipartInterceptor.intercept(MultipartInterceptor.java:98)
br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)

note The full stack trace of the root cause is available in the Apache Tomcat/6.0.20 logs.
Apache Tomcat/6.0.20

Alguém poderia me ajudar?

valew[code]

A primeira coisa que você precisa fazer é colocar seu código entre as tags code. Depois atualize seu vraptor para a versão mais nova (3.1.1).

O erro “Can’t find bundle for base name messages, locale en_US” é na verdade um warning. O erro deve estar sendo ocultado, porém está difícil entender sem indentação do código.

Abraços

Valew pela dica da tag “code”, sou novo no fórum.

Já estou utilizando a versão mais nova do VRaptor.

vc precisa ter um arquivo chamado messages.properties no classpath (por exemplo colocando ele na pasta src/)
e esse arquivo deveria ter um conteúdo parecido com :

#...
nao.eh.imagem = Não é uma imagem
#...

isso pq vc tá usando a forma fluente de validação

Valew mais uma vez Lucas, deu certo.

Agora todo arquivo ele diz que nao é imagem, ele cai aqui dentro:

validator.checking(new Validations(){{
			if(that(imagem, is(notNullValue()), "imagem", "imagem.nula")){
				that(imagem.getContentType(), startsWith("imagem"), "imagem", "nao.eh.imagem");
			}
		}});

O seu form precisa conter o atributo enctype=“multipart/form-data”. Caso voce não colocar isso o upload não será feito.

Abraços

[quote=garcia-jj]O seu form precisa conter o atributo enctype=“multipart/form-data”. Caso voce não colocar isso o upload não será feito.

Abraços[/quote]

Meu formulário já contém esse atributo:

<form action="<c:url value="/produtos/${produto.id }/imagem"/>" method="POST" enctype="multipart/form-data">
		<fieldset>
			<legend>Upload de Imagem</legend>
			<input type="file" name="imagem"/>
			
			<button type="submit">Enviar</button>"
		</fieldset>				
	</form>

Tenho a impressão que sua validação está errada. Mas isso o Lucas pode te dizer melhor.

O vraptor usa o commons-upload como backend para upload de arquivos. O commons-upload jamais retorna um arquivo como null, mas sim com conteúdo vazio. O ideal é você fazer um debug no seu método e ver se o que está retornando.

Valew Garcia, vou ver o que ele retorna.

that(imagem.getContentType(), startsWith("imagem"), "imagem", "nao.eh.imagem"); 

só que o content type de imagem é “image/jpg”, “image/png”, etc… só trocar para startsWith(“image”)

Um erro tolo hein Lucas, valew.

E por último, mais um probleminha…rsrsrrsrs

Pelo que entendi as imagens eram para ser armazenads na pasta “/WEB-INF/imagens”, conforme abaixo:

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

Elas aparecem na listagem de produtos, mas nao consigo achá-las nas pastas do meu projeto, tem idéia onde estou errando?

abraço

Uma coisa que você precisa lembrar é que quando você uma uma IDE (eclipse ou netbeans) você trabalha com os arquivos em sua workspace; e quando você faz o deploy esses arquivos são jogados para o seu servidor (seja tomcat, glassfish, etc). Ou seja, você trabalha com os arquivos em um local e quando faz deploy eles são copiados para outro.

O que está acontecendo é que os arquivos estão sendo gravados no WEB-INF/imagens que está dentro do servidor web. Você provavelmente está procurando pelos arquivos dentro da sua workspace, por isso você não encontra.

e se você colocar as imagens dentro da pasta WEB-INF vc não vai conseguir apontar pra elas de dentro das jsps, pq a pasta WEB-INF fica escondida…

então ou vc cria uma lógica que retorna (como Download) uma imagem dentro do WEB-INF, ou grava as imagens na pasta WebContent mesmo (WebContent/images)